Commit Graph

3032 Commits

Author SHA1 Message Date
Robert Schmidt
900fa704ed bugfix run_asn1c: make make/ninja fail on error
Functionality existed to print all output of asn1c on error, but the
form

    asn1c || cat X

makes the command exit with a 0 exit code (success). Fix by explicitly
returning non-zero exit code in this case:

    asn1c || ( cat X && false )

Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-04-07 15:06:42 +02:00
Robert Schmidt
be9fc79f77 harmonize build_oai -c/-C
Both do practically the same. Harmonize them into one while guaranteeing
backwards compatibility.

Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-04-07 15:06:42 +02:00
Robert Schmidt
57df1ede4b Remove log directory creation: it's not used
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-04-07 15:06:42 +02:00
Robert Schmidt
6684ead115 Correctly handle build_oai --build-lib option
This fixes two problem:

1. an omitted --build-lib library could yield strange grep errors. For
   instance, calling build_oai --build-lib --cmake-opt OPTION passed
   "--cmake-opt" to grep, that does not know this option. Handle by
   explicitly separating options and search pattern through --.
2. Even with this fixed, set -e triggered an exit because grep exits
   with non-zero error code. Remove set -e to have the error handling
   code pass.

With set -e removed, properly check that the build passes.

Update a log line to make it clearer.

Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-04-07 15:06:33 +02:00
Aaron van Diepen
8ec7b4009b Implement SUCI Profile Scheme A for 5G UE
Extend UICC configuration parsing to provide: routing_indicator,
protection_scheme, home_network_public_key, and home_network_public_key_id.
Use the protection_scheme value to decide what SUCI Profile Scheme to
apply during SUCI generation. Add support for Profile Scheme A which
provides ECIES-based encryption using Curve25519 and X9.63 KDF as outlined
in TS 33.501 Section C.3.4.1 Profile A.

When a configuration file specifies an unsupported Profile Scheme,
the NAS layer triggers a fatal error. This occurs either because
Profile Scheme B is unimplemented or the build uses OpenSSL < 3.0,
which lacks Curve25519 and X9.63 KDF support, ensuring users are
informed of the incompatibility.
2026-03-31 00:44:32 +02:00
Robert Schmidt
8107939f08 Change OAI license to CSSL v1.0 (and others)
- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
  scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly

For automated changes based on OAI PL v1.1:

    perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
    perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
    perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml

The rest (cmake, files with missing license, cmake) manually.
2026-03-27 16:36:37 +01:00
Robert Schmidt
6ae4ec37ca Remove most doxygen file-level commands, copyrights, and authors
Remove the \file directive, as it is always superfluous  because the
current file is implicit [1]:

> If the file name is omitted (i.e. the line after \file is left blank)
> then the documentation block that contains the \file command will belong
> to the file it is located in.

Author names and e-mails are not relevant for us: it can always be
inferred from git blame, and is often outdated.

Eurecom code has been contributed and was under OAI PL v1.0/v1.1.

For the cpack package contact: put generic email address that is
independent of an individual and that will remain reachable.

[1] https://www.doxygen.nl/manual/commands.html#cmdfile
2026-03-27 14:52:47 +01:00
Jaroslava Fiedlerova
4973c17392 Merge remote-tracking branch 'origin/remove-old-cuda-ldpc' into integration_2026_w13 (!4007)
Remove old CUDA LDPC implementation

A new implementation is under way in !3955. To simplify the MR, remove the old
LDPC CUDA implementation in a first step.
2026-03-24 10:06:36 +01:00
Romain Beurdouche
3a92eed5b9 fix(build & doc): Remove remaining mentions of ldpc_cuda
* Option to build ldpc_cuda was remaining in the build script
* Build script option to build ldpc_cuda was still used in CI
* Mentions of ldpc_cuda were remaining in the documentation

Note: In the documentation, the example of ldpctest usage that was
loading ldpc_cuda was replaced by an example in which it is loading
ldpc_orig even though this is pointless as it makes ldpctest compare
ldpc_orig with ldpc_orig. On the other hand, it is the only library
other than the default ldpc that uses the former interface.
2026-03-23 13:56:46 +01:00
Jaroslava Fiedlerova
390d96e55a Merge remote-tracking branch 'origin/remove-osd' into integration_2026_w13 (!4004)
Remove OSD, some scripts, oaisim references

The README says:
  It is just generating the XML file and it is placing it in
  $(OPENAIR_TARGETS)/SIMU/EXAMPLE/OSD/WEBXML/ or http://localhost/xmlfile/
  so that the oaisim could pars and run the simulation/emulation

oaisim does not exist anymore, and corresponding simulation cannot be done.
Also, it requires XAMPP and similar technologies, that I think nobody uses
in the context of OAI.
Remove also most references to oaisim.
Remove some scripts that are likely not used by anybody, or straight useless.
2026-03-23 12:26:47 +01:00
Robert Schmidt
7c81c8ad71 Remove most of oaisim references: does not exist anymore 2026-03-19 17:22:32 +01:00
Robert Schmidt
a7bd188042 Remove unused/useless scripts 2026-03-19 17:17:06 +01:00
Teodora
bbecfd5b03 [FHI72] Revert the xran modification introduced in the MR https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3668
1. Remove modifications done in the following xran functions:
process_mbuf_batch();
xran_process_srs_sym().
=> not even used with OAI 7.2 interface.

2. Also, remove xran_fs_get_num_dl_sym_sp() and xran_fs_get_num_ul_sym_sp() introduced in the same MR.

3. Remove LiteOnIgnoreUPSectionIdEnable parameter. Instead, use RunSlotPrbMapBySymbolEnable in a simple way
for xran_process_rx_sym() function.
Explanation: The xran expects UL UP packets with the same section IDs as indicated per UL CP message.
However, the section IDs of received packets are 3 for mixed slot and 13 for UL slot.
2026-03-17 10:16:47 +01:00
Jaroslava Fiedlerova
00394d7892 Merge remote-tracking branch 'origin/CI-bladeRF' into integration_2026_w11 (!3965)
Enable BladeRF support in gNB Docker image

The goal of this MR is to add support for building a gNB image that supports
BladeRF.
2026-03-11 16:10:13 +01:00
Reem Bahsoun
80fb09ba21 Build BladeRF strictly from source.
To avoid version mismatch between built Docker image and BladeRF FW.
2026-03-06 09:19:10 +01:00
Robert Schmidt
356a905d5a Remove RHEL and Rocky 8 from supported distributions 2026-03-04 16:10:07 +01:00
Robert Schmidt
1ea2b1b3ac Upgrade Fedora req to 43 2026-03-02 14:07:08 +01:00
Robert Schmidt
649ae91e59 Remove Ubuntu 20 support
Ubuntu 20 is EOL [1] unless people pay for support. Therefore, remove it
from build_helper. People can still use it, but might need to install a
more recent cmake version (which the next commit will upgrade). The rest
should be the same.

[1] https://ubuntu.com/about/release-cycle
2026-03-02 11:28:09 +01:00
Robert Schmidt
cdfe069c34 Remove unused cmake macros 2026-02-25 16:26:21 +01:00
Robert Schmidt
448f273248 Write NB_ANTENNAS_RX/TX to header file and use in stack
Prior to this commit, constants NB_ANTENNAS_RX/TX are provided on the
command line to each compiler invocation. This has the drawback (1) that
also files that don't need that get the constants, and (2) it is not
easy to find them using ctags or similar, as the only definition is in
CMakeLists.txt (where it is not found).

In this commit, use cmake configure_file() to write a header file with
these constants. The file will be generated during cmake invocation, and
written to <build-dir>/common/cmake_defs.h. The relevant files that
need this definition will pick it from the header.

This has been used previously also in a commit to write git information.

See-also: 8bffd1666d ("Avoid complete rebuild on cmake run with git info change")
2026-02-25 16:26:21 +01:00
Jaroslava Fiedlerova
e2f20eea8a Merge remote-tracking branch 'origin/remove-xran-e' into integration_2026_w08 (!3936)
[FHI72] Remove support for xran E release

All the use cases we tested with E release are working end-to-end with F release.
The near future plan is to support K release which is ongoing in the MR !3444.
2026-02-18 15:03:58 +01:00
Teodora
c68068f144 Remove support for xran E release
All the use cases we tested so far, are supported with xran F release.
Therefore, we can proceed with removing the support with E release.

In addition, our plan is to bring the support for K release which is ongoing activity in
the MR https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3444.
2026-02-18 09:44:08 +01:00
Laurent THOMAS
da7897be04 remove cblas and lapack dependency, as the calling code can't be called in present master branch (likely never worked/fished code 2026-02-16 20:05:04 +01:00
Robert Schmidt
bf325466b3 Merge remote-tracking branch 'origin/bladerf_testing' into integration_2026_w07 (!3894)
Reimplement BladeRF radio driver, make it work for 5G

This MR reimplements the BladeRF radio driver such that it is usable for
5G. On the way, we remove unused code, refactor it for readability, and
update configuration.

Tested:

- 40MHz carrier as gNB
- 20MHz carries as gNB

An initial focus was 2x2, but I did not manage to do this yet.
Documentation on the format is here [1] and there is a helper [2]. I
will do this later.

[1] https://www.nuand.com/bladeRF-doc/libbladeRF/v2.6.0/group___s_t_r_e_a_m_i_n_g___f_o_r_m_a_t.html#gga4c61587834fd4de51a8e2d34e14a73b2a92cfbda7a5577c809e2ff6123f8f30b6
[2] https://www.nuand.com/bladeRF-doc/libbladeRF/v2.6.0/group___s_t_r_e_a_m_i_n_g___f_o_r_m_a_t.html#gac754a927c12cd8aa3fc270e9dd9c108e
2026-02-12 17:04:10 +01:00
Robert Schmidt
abe3ee9624 Fixes bladerf install scripts
- at least in CI, there is no bladerf, so don't try to upgrade a
  firmware (we don't do that either with USRPs)
- the base distro for ubuntu is debian
2026-02-11 18:37:45 +01:00
Robert Schmidt
4e5d92401b Add Debian 12 to list of supported distributions 2026-02-11 18:37:45 +01:00
Robert Schmidt
38975ef120 Allow installation of multiple hardwares in same build_oai invocation
There is no reason to not allow

    ./build_oai -I -w USRP -w BLADERF

To install USRP and BladeRF together (which will be used in the CI in a
later commit). Fix this.
2026-02-11 18:37:45 +01:00
Robert Schmidt
977c484524 Remove option --disable-hardware-dependency 2026-02-11 18:37:45 +01:00
Robert Schmidt
42ef7bac98 Merge remote-tracking branch 'origin/armv8-a-compatibility' into integration_2026_w07 (!3896)
Add fallbacks for ARMv8a to make it compile

The current code, on ARM, uses ARMv8.1-A RDM instructions. Add a
fallback for processors that do not have this instruction set.

Add some specific compile options for this platform.

Add debian 12 to the list of architectures.
2026-02-10 14:46:57 +01:00
Eric Mittag
7b86f61383 Add support for Debian 12 in build_oai 2026-02-10 14:45:10 +01:00
Xin Zhe Khooi
003d72c859 fhi7.2: introduce support for T1a and Ta4 values larger than TTI interval
In xRAN, it appears that T1a/Ta4 values are assumed to be within a TTI.
When T1a/Ta4 values with larger than a TTI are used, this causes two issues: (1) C-plane packets to be generated later than expected and (2) oai_xran_fh_rx_callback() receives the wrong timing information resulting in potentially empty/stale PUSCH/PRACH data to be read.

In this patch, we modify xRAN to make it handle large T1a/Ta4 values properly.
The changes include: (1) three additional variables in offset_num_slots_* (xran_dev.h), (2) modify "xran_timing_create_cbs" and "xran_timer_arm_for_deadline" (xran_cb_proc.c), and (3) revise "tx_cp_dl_cb" and "tx_cp_ul_cb" (xran_main.c).
Additionally, we add additional guard conditions to prevent xran_tx_proc.c from sending U-plane packets when it is not a downlink slot.
2026-02-02 15:00:01 +00:00
Robert Schmidt
bc6f710b23 Merge remote-tracking branch 'origin/uncompressed-f' into integration_2026_w05 (!3821)
[FHI72] [xran F] Handle fragmented (un)compressed packets

In both E and F, the radio-transport fragmentation is not supported, and
all the "fragmented" (not seen as fragments in the xran, only as
sections) packets contain "E-bit" equal to 1. Per spec, the value 1 for
"E-bit" signifies the last fragment of one symbol. For more info, please
see "ecpriSeqid" section in the spec.

In E:

- nRBStart and nRBSize is updated according to the sent/received packet;
- max sections = 1;
- when a packet is fragmented, the xran uses memcpy(pos, iq_data_start,
  size) function, and nothing is stored in start_prbu , num_prbu ,...

In F:

- nRBStart and nRBSize is only used for C-plane messages;
- nPrbElm represents the number of sections for DL only;
- based on the nPrbElm, each section contains UP_nRBStart and UP_nRBSize
  parameters which represent the start and number of PRBs in one section
  or one fragment;
- when a packet is fragmented, the xran uses nSecDesc and sec_desc to
  extract the packet section content, and the data is stored in
  start_prbu , num_prbu ,...

Previous work on the fragmentation in F:

- #884
- !3394 - only increases the XRAN_MAX_FRAGMENT from 4 to 6, since it was
  only tested with BFP 8, but not end-to-end unfortunately. But this MR
  fixes all the issues.

Tested with VVDN RU, 2x2, 16 bits, 100MHz, 30kHz, MTU <= 9216 B, and
Quectel UE RM520N-GL Revision: RM520NGLAAR03A03M4G.
2026-01-29 17:20:54 +01:00
Teodora
b24fd337ba Update xran F release patch
The sufficient number of fragments needed for MTU 1500 and 8b compression is 6.
However, XRAN_MAX_FRAGMENT must be incremented by one (6+1 = 7).

In the MR https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/3394, XRAN_MAX_FRAGMENT was increased to 6,
but the Tx data was actually copied 5 times, and unfortunately I haven't tested end-to-end back then.

This commit was successfully tested with Liteon FR1.
2026-01-29 10:59:24 +01:00
Jaroslava Fiedlerova
efdd43cf66 Merge remote-tracking branch 'origin/debian_redhat_packages' into integration_2026_w05 (!3507)
Create Debian and Redhat packages with CPack

Use CPack in CMakelists in order to create packages, creation command is
available in build_oai script and options description is available in
packages.md
2026-01-28 20:16:22 +01:00
calvin_peyron
8496e88a10 On Fedora libusb-devel is called libusb1-devel 2026-01-23 09:39:38 +01:00
Calvin Peyron
6af6789f65 Fix python-tk has no installation candidate 2026-01-23 09:39:38 +01:00
Bartosz Podrygajlo
27a21cc8aa O-RU: update build_oai to build nr-oru 2026-01-16 11:56:33 +01:00
Robert Schmidt
91e0388180 Merge remote-tracking branch 'origin/liteon_develop_F' into integration_2026_w03 (!3668)
Support beam index for LiteON FR2 RU that needs per symbol section in CP packets

This branch supports beam index for LiteOn FR2 RU and others. It adds
the support of beam index for LiteOn RU that uses per-symbol CP packet
and is a sequel of MR !3605 (merged) that supports beam index for RU
that uses per-slot CP packets.

A. To support LiteOn FR2 RU, the following are needed.

a. Per symbol beamforming. Need separate section for each symbol on CP packet.

b. Handle these two bugs:

- section ID on UP packet is set wrongly to 13 for all sections
- prach eAxC offset starts from 0 instead of from last antenna port
  number used by other channels.

B. Implementation

a. set fh_config->RunSlotPrbMapBySymbolEnable based on the setting in the configuration file

- if disable, the existing per-slot scheme is run on xran.
- if enable, RunSlotPrbMapBySymbolEnable mode is on in xran so that xran
  will generate PrbElm per symbol (aka total of 14)and perform
  per-symbol processing on the corresponding PrbElm.

b. set fh_config->LiteOnIgnoreUPSectionIdEnable based on the setting in
the configuration file if enable, handle 2 "features" of Liteon:

- To handle the section_id = 13 issue on Liteon where section ID is set
  wrongly to 13 for all sections
- To handle the prach eAxC offset issue on Liteon where it starts from 0
  instead of from the end of last antenna port number

c. if fh_config->RunSlotPrbMapBySymbolEnable, OAI FHI

- invoke xran_fh_rx_read_slot_BySymbol() instead of xran_fh_rx_read_slot()
- invoke xran_fh_tx_send_slot_BySymbol() instead of xran_fh_tx_send_slot()

C. Testing

a. Command to test benetel RU

    sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band77.273prb.fhi72.4x4-benetel550_c0.conf --thread-pool 21,22,23,24,25,26,27,28

    Results:
    iperf UDP uplink
    [  5]   0.00-10.22  sec  87.3 MBytes  71.6 Mbits/sec  0.100 ms  370/63081 (0.59%)  receiver
    iperf UDP downlink
    [  5]   0.00-10.00  sec   796 MBytes   668 Mbits/sec  0.017 ms  1824/586404 (0.31%)  receiver

b. Command to test LiteOn FR2 RU

    sudo LD_LIBRARY_PATH=.:$DPDK_INST/lib/x86_64-linux-gnu/ ./nr-softmodem -O /etc/ran_development/CONFs/gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf--thread-pool 21,22,23,24,25,26,27,28

    Result:
    iperf UDP uplink
    [  5]   0.00-10.20  sec  89.9 MBytes  73.9 Mbits/sec  0.156 ms  212/64848 (0.33%)  receiver
    iperf UDP downlink
    [  5]   0.00-10.00  sec   361 MBytes   303 Mbits/sec  0.077 ms  277662/542891 (51%)  receiver

D. Difference between LiteOn FR2 E release configuration file and that for F release is

    diff gnb.sa.band78.66prb.fhi72.2x2-liteon-KB.conf gnb.sa.band78.66prb.fhi72.2x2-liteon-F-Release.conf 39d38

    <     beam_weights = [1, 1];
    225a225
    >     beam_weights = [1];
    312c312,313
    <   mtu = 1500; # check if xran uses this properly
    ---
    >   #mtu = 1500; # check if xran uses this properly
    >   mtu = 9000; # check if xran uses this properly
    313a315,316
    >   RunSlotPrbMapBySymbol = 1;
    >   LiteOnIgnoreUPSectionId = 1;
2026-01-14 14:47:52 +01:00
Mario Joa-Ng
48247ecc1d Add F release patch fh_config parameters RunSlotPrbMapBySymbol and LiteOnIgnoreUPSectionId.
Add the F patch that work on both Benetel and LiteOn RU. support
fh_config parameters RunSlotPrbMapBySymbol and LiteOnIgnoreUPSectionId.
Change version number.
2026-01-14 14:33:30 +01:00
Rakesh Mundlamuri
3d68a44da0 Introduce SRS physical simulator 2026-01-09 16:58:26 +05:30
Robert Schmidt
b1fa6e6cdf Remove unused CMake helper files
These files are not used anywhere. The only remaining cmake find files
are:

- findarmral and findxran: used by FHI7.2 driver
- findsctp: used by top-level CMakeLists.txt
- findgnutls: NOT actually used but GnuTLS is a dependency of websrv, so
  I leave it for the moment (should be removed if the webserver is
  removed)

Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-01-06 08:35:12 +01:00
Robert Schmidt
ca707b3987 Remove old MME/eNB instructions
There is no HSS/MME in this repository, which is the majority of this
file. Remove it, since it is outdated.

Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-01-06 08:26:45 +01:00
Robert Schmidt
8176fd3063 Remove old FlexRAN file
Setup routes was added by the author of FlexRAN. The UEs always set up
routes automatically, and this file is therefore not needed.

See-also: 287c182925 ("Remove FlexRAN")
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-01-06 08:25:55 +01:00
Robert Schmidt
40ea8f7592 Remove unused snap_environment.sh
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
2026-01-06 08:18:34 +01:00
Jaroslava Fiedlerova
0226510c4a Merge remote-tracking branch 'origin/fapi-stop-exchange' into integration_2025_w48 (!3561)
Implementation of STOP exchange

This implements the STOP.request/indication for all 3 transport mechanisms, the
VNF will send the STOP.request to the PNF, indicating it will disconnect, and
await a STOP.indication from the PNF

The WLS VNF is reworked to be able to start before the PNF, by calling call
rte_eal_init and rte_dev_probe to determine if dpdk has been initialized
properly, before calling rte_eal_init in the intended process when it is
appropriate to do so
2025-11-27 15:01:39 +01:00
Robert Schmidt
7c18dfd93a Merge remote-tracking branch 'origin/remove-benetel-radio-drivers' into integration_2025_w43 (!3719)
Remove Benetel-specific radio drivers

These drivers are superseded by the O-RAN 7.2 FHI
2025-10-23 19:19:24 +02:00
Rúben Soares Silva
c83bd87459 Fixup WLS documentation and Makefile patch 2025-10-23 14:08:37 +01:00
Robert Schmidt
ece138134b build_oai: remove non-existing oran_fhlib_4g option 2025-10-23 10:03:28 +02:00
Robert Schmidt
8ecda65d55 Remove Benetel radio drivers
These drivers are superseded by the O-RAN 7.2 FHI.
2025-10-23 10:00:08 +02:00
Robert Schmidt
af37aaee00 Merge remote-tracking branch 'origin/oran_beamforming' into integration_2025_w43 (!3605)
Support beam index in OAI 7.2 Fronthaul Interface

This branch supports beam index in OAI 7.2 Fronthaul Interface.

- For CP DL (PDSCH), nBeamIndex of the corresponding prbMapElm is set
  when sending IQ data in oran_fh_if4p5_south_out. nBeamIndex of the
  corresponding prbMapElm is set when sending IQ data in
  oran_fh_if4p5_south_out.
- For CP UL (PUSCH and PRACH), nBeamIndex of the corresponding prbMapElm
  is set in oran_fh_if4p5_south_out.

In addition, it fixes a couple of issues

- XRAN hardcodes nBeamIndex of PRACH to zero. Modify XRAN to support
  setting of nBeamIndex of PRACH and update xran F release patch.
- Fix the bug in calculating fh_config->neAxc where num_beams_period is
  multiplified twice

Testing methodology: Use Benetel O_RU for testing even though it does
not support beamforming. With successful registration and data transfer,
one could check the pcap on the fronthaul interface to see if CP packets
are with the right beam index.

Results:

1. Verified that CP-packets for SSB, DCI, PDSCH, PRACH, PDSCH, PUSCH,
   CSI-RS and SRS are with the right beam index
2. Verified that there is no side-effect on Benetel O_RU. UE could
   register properly.
3. Verified 4 SSB with ssb_PositionsInBurst_Bitmap = 85. Could see SSB
   and PRACH with 4 different indices.
2025-10-21 09:09:03 +02:00