Skip to content

Loading builds...

Changes

#4679 (Feb 10, 2026, 9:45:10 AM)

logging: Support nonblocking-io for log target stderr & file, make it default

The nonblocking-io used to be the mode used until recently, where wq
only was used if the write buffer was full.
This is more performant that always waiting for poll() to write, plus
the fact that we write to system synchronously, hence seeing output
immediatelly or not losing it if program crashes.
Furthermore, It turns out using wq in multithreaded programs may cause
problems, so better switch back to using nonblocking-io by default.

Related: OS#6947
Change-Id: I46420f4b174d3a9ed01e993e2e89aea3b46c0dd7
Pau Espin Pedrol at

#4677 (Feb 9, 2026, 2:25:07 PM)

osmo_io: Move function declaration to internal header

Change-Id: I25ffb94e00225bcdc565f56a3f0f7834df00e974
Pau Espin Pedrol at
osmo_io_uring: Split global init from per-thread init

osmo_iofd_init() is expected to be called per-thread, while some code in
osmo_iofd_uring_init() was only expected to be called once.

Change-Id: Ifa5c46d7532ea49869f3cfe7268fdd082906fd10
Pau Espin Pedrol at
osmo_io: Lazy-initialize during osmo_iofd_setup()

This way new threads (!=main) don't need to explicitly call
osmo_iofd_init() explicitly before using osmo_io. This is specially
useful for threads using osmo_io indirectly, eg, when logging.

The osmo_iofd_setup() API is really the only main API which requires
initialization. All other APIs requiring it come after osmo_iofd_setup()
since they use an osmo_iofd pointer.

Change-Id: Ia543c1b9d111c929cd9dbed266b6d21b74e47e4b
Pau Espin Pedrol at

#4671 (Feb 4, 2026, 2:20:07 PM)

Add Emscripten build support and JS callback logging backend

This change enables building libosmocore for sandboxed, non-POSIX
environments, specifically WebAssembly targets produced via the
Emscripten toolchain.

The broader motivation is to allow partial execution of selected
Osmocom components in isolated runtime environments where direct access
to hardware and traditional operating system facilities (filesystem,
sockets, privileged execution) is not available.

One intended use case is running a GSM 2G base station where the
radio-facing components are executed inside a web environment, while
the remaining Osmocom stack and core network components continue to run
unchanged on a conventional backend server. In this model, highly
stripped-down variants of osmo-bts and osmo-trx are built as static
WebAssembly libraries and executed in the browser, while depending on
core libraries such as libosmocore, libosmo-netif, and libosmo-abis.

A practical advantage of this approach is that no deployment or
privileged setup is required on the radio endpoint side. A user can
instantiate a radio endpoint with minimal configuration, while all
stateful logic and operational complexity remains centralized on the
backend. Multiple such radio endpoints may connect to the same backend
core network, effectively forming a single logical network from the
core network perspective, independent of the physical location of the
radio endpoints.

Existing libosmocore build logic and platform assumptions rely on the
availability of POSIX APIs and OS services which are not present in
WebAssembly runtimes. This currently prevents libosmocore from being
built for such targets without targeted, build-time adjustments. This
patch introduces the minimal set of changes required to enable such
builds, without affecting native platforms.

As part of this groundwork, a minimal callback-based logging hook is
introduced. When building for Emscripten, this hook allows forwarding
log messages to an external environment via a user-provided JavaScript
callback. This enables integration with browser-side logging or UI
infrastructure without introducing new logging backends or runtime
dependencies. For all other build targets, the hook resolves to a no-op
implementation and does not alter existing logging behavior.

No runtime behavior, protocol semantics, or network interactions are
changed by this patch. All modifications are strictly limited to
build-time and platform-specific code paths and are only active when
targeting Emscripten. Native builds and existing deployment scenarios
remain unaffected.

This patch is intended as groundwork. Follow-up changes, proposed
separately and incrementally, may extend similar support to other
Osmocom components such as libosmo-netif, libosmo-abis, osmo-bts, and
osmo-trx, while keeping all such changes optional and isolated from
native builds.

Change-Id: Ia8d5f4bb6570b5e055826f3a051e5e5896866e31
dtv.comp at

#4668 (Feb 2, 2026, 4:05:08 PM)

vty: Use osmo_fd_{write,read}_enable() API helper

Change-Id: Icba439fb33a29626ffce9ca1d61d30e88426f526
Pau Espin Pedrol at

#4667 (Feb 2, 2026, 1:55:06 PM)

Implement log file target using osmo_io

Reuse (struct log_target)->tgt_file->wqueue->except_cb to store the iofd
pointer internally, since we are not allowed to change the struct
log_target because it's public and we don't want to break the ABI.
Using the wqueue except_cb is fine since that field was never used.

Related: OS#6918
Change-Id: Ieb6420246454ef59442b1fd7b1d14e2c00fa69a5
Pau Espin Pedrol at
Use same queue length for gsmtap_log and gsmtap_file

Take the chance to also deduplicate MAX_LOG_SIZE.

Change-Id: I3772d291f97626ee325731f3515a5110eda70d3d
Pau Espin Pedrol at
osmo_io: Remove outdated comment in API doc of osmo_iofd_set_io_buffers()

Multiple iov buffers are supported in poll backend since
4272cd46b1e5b264e6f6b65d38bcb08e3a139a9e.

Related: OS#6705
Change-Id: I9b75f3597081c6cd7e24f75f0e289b93edb3aa86
Pau Espin Pedrol at
osmo_io: Allow fetching maximum value allowed by osmo_iofd_set_io_buffers()

Before this patch, there's no way for a user of the API to know whether
a requested buffers value is actually going to be accepted or not.

Change-Id: Id3d8413c119eb3d9b60aa068295a59561236938c
Pau Espin Pedrol at
logging_file: Request up to 8 iofd write buffers if available

This should help in decreasing latency between submitting a logging line
and getting it written to file. It should, for the same reason, optimize
CPU use.

Change-Id: Ia88b27948922d278e0f72fc2aac4b4ae88465b4d
Pau Espin Pedrol at

#4666 (Feb 2, 2026, 9:40:09 AM)

osmo_io: Introduce API osmo_iofd_get_txqueue_max_length()

Change-Id: I92526aa554fc87734fae3fac0ad650d17bf52bb5
Pau Espin Pedrol at
logging_file: Clean log_target_file_reopen()

Move specific assert for wq further below.
Do early return to get rid of extra indentation.

Change-Id: Ibcb50320ad80b034115cccc3b7ab90501ac1d091
Pau Espin Pedrol at

#4665 (Feb 2, 2026, 8:45:08 AM)

logging: Also Avoid infinite loop/deadlock in log_check_level()

A LOG() macro being called inside an already-logging path will first
call log_check_level() before calling osmo_vlogp(). Since calling
happens with the mutex hold, it has been seen to deadlock in eg.
osmo-hnbgw.

Change-Id: I0098629b335b3aa174b49fd79c33d22b04bc4785
Pau Espin Pedrol at

#4661 (Jan 30, 2026, 1:15:08 PM)

Fix 'logging: Avoid infinite loop logging inside logging path'

I didn't see the early return of log_cache_check(), which should leave
the logging_active variable as true forever.

Fixes: bc400626b28c85fe0f52ce25947a90650b0d06b5
Change-Id: I13ed182688597c7da279a50bf057eff6d13f0867
Pau Espin Pedrol at

#4660 (Jan 30, 2026, 9:55:09 AM)

logging: Avoid infinite loop logging inside logging path

If eg. gsmtap_log target is requested to log a message but the iofd
wqueue is full, it may try to log an error message, which will create an
infinite stack loop.

Change-Id: If3b8c0ee97537242162558fdd1c99f03b32af811
Pau Espin Pedrol at

#4659 (Jan 30, 2026, 9:45:09 AM)

stats_tcp.c: Remove unneeded EMBEDDED check

The HAVE_LINUX_TCP define check should be enough.

Change-Id: I68cb49925aa49ad97b266638d41f38c22fc32000
Pau Espin Pedrol at

#4658 (Jan 30, 2026, 9:40:08 AM)

logging_file: Avoid reopening file for stderr

target->tgt_file.fname is NULL for stderr log target.

Change-Id: I4a551b0c434c480e78852a0a4873700eac2f5853
Pau Espin Pedrol at
logging_file: Fix log_target_file_switch_to_stream on stderr

In stderr log target, the bfd of the wq was left registered despite
freeing the wq, which ended up in the callback being called and the
freed wq being used.

Change-Id: I1c0d833fb8ae82d1dd54e44cc2fc8be80d5e1b4b
Pau Espin Pedrol at

#4656 (Jan 29, 2026, 11:00:09 AM)

core: guard TCP stats on availability of linux/tcp.h

Detect availability of linux/tcp.h at configure time
and build TCP statistics code conditionally based on that.

This replaces platform-specific conditionals with proper feature checks
and avoids build failures on systems lacking Linux TCP headers or types
(e.g. non-Linux or cross-build environments).

When TCP_INFO support is unavailable, the public API remains unchanged,
but all related functions return -ENOTSUP.

No functional changes on systems where linux/tcp.h are available.

Change-Id: Ibcd00f15131b0291f0b10eca51401c518b77cc39
Pau Espin Pedrol at
core: always build tun.c and gate TUN support by headers

Always build tun.c and move platform-specific checks into the
implementation.

Guard the TUN-specific code paths based on the availability of
linux/if_tun.h detected at configure time. If TUN support is not
available, osmo_tundev_open() returns -ENOTSUP.

This keeps the public TUN API available while disabling unsupported
functionality in a capability-based way.

Change-Id: I6d1ea1644d12ef59a54cf2f73b9155def58b17a9
Pau Espin Pedrol at
core: guard Linux netlink headers by libmnl usage

Only include Linux-specific netlink headers when the libmnl backend
is enabled.

The code paths requiring <linux/if_link.h> and <linux/rtnetlink.h>
are entirely guarded by ENABLE_LIBMNL conditionals, so the headers should
not be included unconditionally.

This avoids pulling in Linux-only headers when the corresponding
backend is not built.

Change-Id: I0b681deb1f1e025e3ea9996f19b1de06a5feb408
Pau Espin Pedrol at

#4654 (Jan 28, 2026, 11:15:10 AM)

osmo_io: Fix misalignment of iofd->cmsg used as struct cmsghdr

Fixes following ASAN runtime error:
"""
src/stream.c:398:47: runtime error: member access within misaligned address 0x516000012b81 for type 'struct cmsghdr', which requires 8 byte alignment
0x516000012b81: note: pointer points here
51 00 00  00 30 00 00 00 00 00 00  00 84 00 00 00 01 00 00  00 00 00 00 00 00 00 00  00 00 00 00 03
              ^
"""

Current GCC documentation [1] states that __attribute__ ((__aligned__
(alignment))) is the older sytnax. The newer _Alignas mimics the
standarized alignas() in C23. Since we build with CLAGS=-std=gnu11 we
are fine using _Alignas, which was introduced in C11.

[1] https://www.gnu.org/software/c-intro-and-ref/manual/html_node/Type-Alignment.html

Related: OS#6905
Change-Id: Ia80dfc4dbffe85514b18dcf8d36b85bfafd76d64
Pau Espin Pedrol at

#4651 (Jan 26, 2026, 9:10:05 PM)

socket_compat.h improvements to always have struct osmo_sockaddr available

Having a #if (!EMBEDDED) based on compiler defined variable is not a
good idea. Instead, add minimal sys/socket.h and netient/in.h to always
have the definition of struct osmo_sockaddr available.

Change-Id: I5b10e09770727c72812af15360ab3385b957509b
Pau Espin Pedrol at
remove references to define EMBEDDED in public headers

It's not a good idea to base opt-in/out of code in public headers based
on some specific non-standard define being set at compile time when
calling the compiler. Get rid of those references; Now that
osmocom/core/socket.h can be included thanks to improved
osmocom/core/socket_compat.h, it shouldn't be a problem.

Change-Id: I7a657d67077dfbe861959c6123eb9163bc791694
Pau Espin Pedrol at
logging: Move log target file to its own file

We already have all other log_target implementations each on its own
file. Move the file (and stderr, a specific case of file) into its own
file too, properly separating most file-specific logic from general
logging logic.

Change-Id: I8e32e31c75b66ff0649d92c2f469f8895689fbad
Pau Espin Pedrol at

#4650 (Jan 26, 2026, 11:35:08 AM)

osmo_io: Add assert to validate inconditional

The do-while loop is entered:
* First time: "tail_msg != NULL" (since it was set to "msg").
* Subsequent times: coming from "while" condition:
** tail_msg != NULL
** res == IOFD_SEG_ACT_HANDLE_MORE, which means iofd->pending != NULL.

Hence, always either "iofd->pending" or "tail_msg" is valid when entering
the loop, and hence "msg" will also be valid.

Related: Coverity CID#557196
Change-Id: If29363edfba576370e306fb5b160d9f038018130
Pau Espin Pedrol at

#4649 (Jan 26, 2026, 11:15:07 AM)

osmo_io.h: Avoid including sys/socket.h

sys/socket.h may not always be available (eg. arm-none-eabi toolchain).
In the header file we only really need the forward declaration of struct
msghdr, so simply do that.

Change-Id: I5bcba8f72a2be6161d7782a3100d25a7025341d0
Pau Espin Pedrol at
socket.h: Include netinet/in.h instead of arpa/inet.h

In socket.h we are mainly interested in netinet/int.h, since that's the
one defining INET_ADDRSTRLEN, struct sockaddr_in, struct in_addr, ec.

Header arpa/inet.h usually defines several functions which use those,
like htonl(), inet_ntop(), etc.

See POSIX:
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/arpa_inet.h.html#tag_13_03
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html

Change-Id: I03919c4adc962bbcfabc9030c6f12c0e10ff060c
Pau Espin Pedrol at
configure.ac: Add arpa/inet.h to AC_CHECK_HEADERS

We use arpa/inet.h in several places in the code, so it's good to look
up for presence even if it's only to debug toolchain compatibility.

Change-Id: Ib2d1fb3efb1dcb429b511698691249c257e00720
Pau Espin Pedrol at

#4647 (Jan 25, 2026, 10:10:06 PM)

build: keep netns API public and gate features with HAVE_*

The netns API was previously guarded by platform-specific preprocessor
conditions (e.g. !EMBEDDED and defined(__linux__)), which caused the
netns headers and implementation to be entirely excluded from non-Linux
builds such as Emscripten. This in turn led to build failures in code
depending on the netns API, as the symbols and declarations were not
available at all.

Always build netns.c and keep the public declarations available
for non-embedded builds. Move platform/feature conditionals into the
implementation: guard the netns code paths with HAVE_SETNS/HAVE_UNSHARE/
HAVE_MOUNT and HAVE_CLONE_NEWNET, and return -ENOTSUP when the required
functionality is not available.

Add configure-time checks for the required headers/functions and for the
CLONE_NEWNET declaration, defining the
corresponding HAVE_* macros.

No functional changes intended for platforms where netns is available.

Change-Id: I2322eb2936bea35596f1fd6b6a713ea5f997b1ea
dtv.comp at
core: remove SCTP include from osmo_io_internal.h

No functional changes intended.

Change-Id: Icd626d908192a954d55d76a46d7cc863ed332631
dtv.comp at

#4646 (Jan 25, 2026, 10:05:08 PM)

core: fix printf format casts for struct timeval fields

Explicitly cast struct timeval fields to long when passing them to
printf-style functions.

This avoids compiler warnings/errors on platforms where tv_sec or
tv_usec are not exactly of type long, while keeping the existing log
and control output unchanged.

Change-Id: Icac9e392c728948a7976970658e37f5e0da41709
dtv.comp at
vty: guard definition of _XOPEN_SOURCE

Define _XOPEN_SOURCE only if it is not already provided by the build
environment.

This avoids redefinition warnings/errors while ensuring required POSIX
interfaces are available.

Change-Id: I4f53aff1afef02abce7cb70d1b29080ba900ff41
dtv.comp at

#4643 (Jan 23, 2026, 10:50:05 AM)

osmo_io: Support rx of segments up to ~UINT16_MAX

Previously if we recevied a big chunk (near UINT16_MAX), we would hit
the following assert in iofd_msgb_alloc2(), because our msgb
implementation can only handle sizes up to 16 bit length, counting
headroom + data length:
"OSMO_ASSERT(size + headroom <= 0xffff);".

This new improved logic allows handling segments of up to ~UINT16_MAX
which may come in in multiple read calls. It also adds logic to catch
received segments greater than UINT16_MAX (or buggy segment_cb or buggy
peer transmitting to us) and notifies the user of a broken stream
through read_cb() in that case.

test_segmentation_uint16_max() is added to osmo_io_test, which would
abort without this patch applied.

Related: SYS#7842
Change-Id: I8c11a7edbed2335ada40a1f93d081041974c3586
Pau Espin Pedrol at
osmo_io: Propagate segment_cb errors to the read_cb

Previous logic was to drop an entire msgb in the stream and pretend it
can continue working that way, which clearly makes no sense.
Instead, if segment_cb detects some problem (eg. buggy peer sending
corrupted data according to protocol), propagate the issue through
read_cb() so that the app can act on it, ie. most likely close the
connection.

Related: SYS#7842
Change-Id: I572e68df6799b903507229a9beee6fa7d7d6d652
Pau Espin Pedrol at

#4642 (Jan 23, 2026, 10:15:09 AM)

logging: Add APIs to set/get log_{target,context} fields

Change-Id: Ie48e7e635feb91509b9c034394df4fb16cb931a3
Pau Espin Pedrol at
gb: Avoid accessing struct log_target members directly

Change-Id: Idb2f7f3736f0a22a091a702e23ef7cf58e56cfa9
Pau Espin Pedrol at
Remove unused private API log_target_create_file_stream()

This function was never added to the logging.h (despite it was not
static and it was inside libosmocore.map).
It is actually used nowhere, and changing it to static made the compiler
warn about it. Remove it.

Change-Id: Ia30c6b47cfcbb54e7c2c43b877cd9554dc596abf
Pau Espin Pedrol at

#4641 (Jan 23, 2026, 9:20:07 AM)

core: always build osmo_sock_multiaddr_* helpers

Always build the public osmo_sock_multiaddr_* helper functions,
independent of HAVE_LIBSCTP.

Move the HAVE_LIBSCTP checks inside the functions and limit them
to the SCTP-specific code paths: when IPPROTO_SCTP is requested
without libsctp support, return -ENOTSUP, while non-SCTP protocols
continue to work as before.

This fixes link failures in libosmo-netif when building with
--disable-libsctp.

Change-Id: I3e70b7cd6cb4d022252e6ddc70a42ca5eea72bb1
Pau Espin Pedrol at

#4639 (Jan 22, 2026, 9:55:07 PM)

osmo_io: Make iofd_handle_segmented_read() static

Change-Id: I6671380ad071e23445c3e38c0b9700af66998af1
Pau Espin Pedrol at
osmo_io: Reorder iofd_handle_segmented_read()

All other similar functions have first the int rc and later the struct
msgb; fix this one being different.

Change-Id: I88683334e77901776c806dad776ef46ea20b4480
Pau Espin Pedrol at
osmo_io: Assert osmo_iofd_set_alloc_info() params fit in a 16bit value

Related: SYS#7842
Change-Id: I32822574db8997a02bf18b71bf6ab596e726cb82
Pau Espin Pedrol at

#4637 (Jan 21, 2026, 9:10:08 AM)

Detect struct in6_addr.s6_addr32 via AC_CHECK_MEMBER and use HAVE_IN6_ADDR_S6_ADDR32 instead of __linux__.

No functional changes intended, this is a preparatory refactor to keep
follow-up patches focused and easier to review.

Change-Id: I29385fde0f1e6c6cc73cd1488befdef9040cc28e
dtv.comp at

#4635 (Jan 20, 2026, 11:05:07 AM)

contrib/jenkins_arm.sh: Remove explicit configure.sh disable args

Since --enable-embedded was reworked in
9197c1ac176ab8aa33f82e059404dcd482577a31, it is no longer needed to pass
those flags explicitly for proper checking, since --enable-embedded
preset takes care of enabling/disabling them and do the related checks.

Change-Id: Ie1f99305c198a4e164d54ce7090c9fc67e99a891
Pau Espin Pedrol at

#475 (Sep 15, 2018, 8:00:08 AM)

gsm0808: fix wrong codec defaults for OFR_AMR_WB
3GPP TS 48.008 chapter 3.2.2.103 states that the configuration bits of
OFR_AMR_WB are coded as follows:
"S0, S2, S4 indicates the supported Codec Configurations. S1, S3, S5,
S6, S7 are reserved and coded with zeroes."
The current default setting of 0x3F violates this requirement. Lets set
the "forbidden" settings zu zero and keep only the allowed ones.
Change-Id: I4a481def59e9c98cfdcafc2b80c0ac7df0c14130
pmaier@sysmocom.de at
gsm0808: add function to convert amr gsm0408 setings to gsm0808
Add a function to convert struct gsm48_multi_rate_conf, which holds the
codec settings for AMR, to S0-S15 bit representation as defined in 3GPP
TS 48.008 3.2.2.49
Change-Id: I4e656731b16621736c7a2f4e64d9ce63b1064e98 Related: OS#3548
pmaier@sysmocom.de at