Skip to content

Loading builds...

Changes

#767 (Mar 27, 2026, 12:46:08 AM)

pfcp_peer: implement periodic PFCP heartbeat

Add a heartbeat_interval parameter to the pfcp_peer config section.
When non-zero, pfcp_peer sends a periodic Heartbeat Request to the UPF
at the configured interval using a named gen_statem timeout (hb_timer).
The timer is started on entry to the connected state and cancelled on
re-entry to the connecting state.  Default is 10000 ms (10 seconds).

Change-Id: I306324f8eca325202a3fa23125854db9d5eaab38
laforge at

#766 (Mar 26, 2026, 11:51:10 AM)

s1ap_proxy: fix build_erab_setup_response_failure() to report all E-RABs

The previous implementation only included the first E-RAB from the
registry in the failure response (a FIXME was left in place).

Fix it to extract all E-RAB IDs from the original E-RAB SETUP REQUEST
and include each of them in the failure list, as required by 3GPP.

Change-Id: I7933fceb0edcdfdc95ace35416297b11c83f0bc9
Related: osmo-ttcn3-hacks.git I8a5dc338d28013dc85e1ce4b3bdac92cb3b35304
Vadim Yanitskiy at

#765 (Mar 26, 2026, 10:11:09 AM)

pfcp_peer: tune Heartbeat Request/Response logging

Reduce verbosity of the Tx/Rx Heartbeat Req/Resp log messages from
LOG_INFO to LOG_DEBUG in preparation for periodic heartbeat support.
Without this change, periodic heartbeats would flood the logging.

Change-Id: I6435cdf64fd86fa5358d57ea4d56dcad8eb9e69e
Vadim Yanitskiy at

#763 (Mar 25, 2026, 2:16:07 PM)

[REST] PfcpAssocState: field 'lrts' is required

The local RTS is always known and thus always gets included regardless
of the PFCP association state.  Only the remote RTS is optional.

Change-Id: Ic766ebc56ce1810fc27cb49ddcac50bc94e539d9
Related: osmo-ttcn3-hacks.git I332e95a32935e0c8da99e600e8d30af14bd36b16
Vadim Yanitskiy at
gtpu_kpi: use ?ENV_DEFAULT_GTPU_KPI_{TABLE_NAME,INTERVAL}

Change-Id: Ia8194966b20da1adc26c02f416b8ec0508191d98
Vadim Yanitskiy at
config/sys.config: group pfcp_peer params into a map

Following the same pattern as sctp_{client,server}, group the flat
pfcp_loc_addr/pfcp_rem_addr environment variables into a pfcp_peer
map.  The old flat keys are still supported for backwards compat.

Changes:
* osmo_s1gw_sup: add pfcp_cfg(), merging legacy flat keys with the new
  pfcp_peer map (new takes priority); store the resolved config back via
  set_env(pfcp_peer, ...) so all consumers see a single canonical map
* pfcp_peer: change start_link/2 to start_link/1 taking a cfg() map;
  simplify init() using sctp_common:parse_addr/1; add cfg() type
* rest_server: read pfcp laddr/raddr from the pfcp_peer map

Change-Id: Iba954746fe20e6b9eeaec3196e1f83e3fc3e7fc2
Vadim Yanitskiy at
pfcp_peer: make assoc_setup and heartbeat_req timeouts configurable

Add assoc_setup_timeout and heartbeat_req_timeout as optional fields
in the pfcp_peer config map, with 2000 ms defaults.  Store the full
cfg() map in #peer_state{} and read values from it with maps:get/3
at the point of use.

Change-Id: I58a472a3bbbbad029a2f0246b084428ab3b1905c
Vadim Yanitskiy at

#757 (Mar 20, 2026, 9:31:08 PM)

contrib/jenkins_manuals: fix doc/manuals paths

Change-Id: Ibfccefec7e44a4803d4ff8ad061db395fc498b89
Oliver Smith at
[REST] Add MME source address/port to EnbItem

The enb_proxy now captures the local address and port of the S1GW-MME
SCTP connection (mme_saddr/mme_sport) at comm_up and includes them in
conn_info().  Expose this info through the REST API (EnbItem schema),
show it as a new column/row in the CLI (enb_list/enb_info).

Change-Id: I15bbddf96ac7d5b6f9962a8d745db58fdec334e7
Related: SYS#7066
Vadim Yanitskiy at
[REST] Add PLMN/eNB IDs to EnbItem

Change-Id: I79690223a34afea5e6661125ac04f98462dadb03
Related: SYS#7066
Vadim Yanitskiy at
doc/manuals: cli: shorten enb_list example table

The full enb_list table with all address columns is too wide to fit
on a page and does not render well in PDF.  Collapse the address
columns with '...'; add a note that they are omitted for readability.

Change-Id: I4e25233a3e77358060f1098e97907c93deab334b
Related: OS#6671
Vadim Yanitskiy at
enb_{proxy,registry}: signal MME conn info on SCTP comm_up

Previously, mme_aid/mme_saddr/mme_sport were only signalled to the
enb_registry once the S1 Setup procedure completed.  This meant the
REST API could not show MME connection details for eNBs stuck in
wait_s1setup_rsp state (e.g. due to a slow or retrying MME).

Add notify_mme_comm_up/2, called at SCTP comm_up, which stores the full
conn_info (including mme_aid, mme_saddr, mme_sport) in the registry as
soon as the SCTP connection is established.

notify_mme_connected/2 is simplified to notify_mme_connected/1: it now
only flips the state to 'connected', since conn_info is already stored.

Change-Id: Iea9ba4fdf961e6cd262edc154884a2eee3d95355
Related: SYS#7066
Vadim Yanitskiy at
enb_proxy: split conn_info() into mme_conn_info() and proxy_info()

The old conn_info() conflated two distinct concerns: the MME SCTP
connection info stored in enb_registry (aid, saddr, sport) and the
broader operational state used for introspection (handler pid, enb
connection info, etc.).  Mixing them forced enb_registry to hold a
handler pid it has no business knowing about, and required rest_server
to extract that pid just to reach s1ap_proxy for E-RAB listing.

Split into two distinct types:

* mme_conn_info() - pure MME SCTP connection info (aid, saddr, sport),
  stored in the enb_registry and signalled via notify_mme_comm_up/2.
  The `mme_` prefix is dropped from field names as the type name
  provides the context.

* proxy_info() - richer operational snapshot (handler, enb_handle,
  enb_conn_info, mme_conn_info, genb_id_str, mme_info), returned by
  fetch_info/1 for introspection/debugging purposes.

Additionally:

* Add fetch_erab_list/1 to enb_proxy, delegating internally to
  s1ap_proxy:fetch_erab_list/1 via the cached handler pid.  This
  allows the rest_server to obtain a list of E-RAB without having
  to obtain pid of the s1ap_proxy and interact with it.

* Remove separate enb_aid/mme_aid/mme_saddr/mme_sport state fields;
  enb_aid is now read directly from enb_conn_info, and the MME fields
  are grouped in mme_conn_info.

Change-Id: Ia428ceb4762f972211e9b790688dc89fb5b8a274
Related: SYS#7066
Vadim Yanitskiy at
enb_proxy: add missing mme_info() to proxy_info()

As a bonus, `tried_mmes` now only serves its actual purpose - tracking
which MMEs have already been tried for selection filtering - rather
than being abused as a way to retrieve the current MME name.

Change-Id: Ibbb293d9e68b7c3a8c3ca7ee73132dbda3f2bf97
Related: SYS#7066
Vadim Yanitskiy at
s1ap_proxy: add public erab_list() type

Change-Id: I21a674537d1d9f16fdb319aaf2d758ba0906b407
Vadim Yanitskiy at
rest_server: fix TOC/TOU race when listing/fetching E-RABs

The list of E-RAB FSM pids is a snapshot taken at one point in time.
By the time we interrogate each erab_fsm process individually, any of
them may have already terminated (e.g. bearer released mid-request).
The current code fails to generate a response if this happens.

* fetch_erab_info/1: add a pid() clause that wraps erab_list_item/1
  in a try/catch, returning 'error' if the process is gone.

* fetch_erab_info/1: catch both exit forms
** `{noproc, _}` raised by gen_statem:call/2 on a monitored pid, and
** the bare noproc atom for other code paths.

* fetch_erab_list/1: switch from lists:map to lists:filtermap and
  call fetch_erab_info/1 per E-RAB, silently dropping any that died
  between the snapshot and the per-process interrogation.

Change-Id: I160b413aa535f2379ad4e40a3ae8f37c5bce2067
Related: SYS#7066
Vadim Yanitskiy at
rest_server: log received requests (as debug)

Change-Id: I25da9662fb98a0eafcedfde21b12a937225f5fb9
Related: SYS#7066
Vadim Yanitskiy at