These guidelines provide standard default conventions for repository operations. Explicit user instructions always take precedence and override these guidelines.
OpenAirInterface 5G: 4G/5G RAN stack (UE, eNB, gNB) implementing 3GPP standards.
Use cmake directly, not the build_oai wrapper (the exception: ./build_oai -I once, to
install system dependencies on a fresh machine).
mkdir -p build && cd build
cmake .. -GNinja
ninja # or target it: ninja nr-softmodem nr-uesoftmodemopenair1: PHY layeropenair2: MAC / RLC / PDCP / RRC / SDAP layersopenair3: NAS / NGAP / GTP layersradio: Radio drivers (rfsimulator, USRP, etc.)fronthaul: Native OAI 7.2x fronthaul splitexecutables: gNB / UE / CU / DU top-level main entrypointsci-scripts: Official CI test harness and execution scripts (see Verification below)
See doc/code-style-contrib.md. In short: 2-space indent, no tabs, 132-column
limit, respect .clang-format, strong types (c16_t not uint32_t for IQ
samples), AssertFatal()/DevAssert() for invariants — not error handling.
Be concise and to the point in responses, commit messages, and code comments.
Don't leave "in-progress"/WIP/TODO markers or temporary debug logging
(LOG_E/print statements added only to trace a bug) in code you consider
finished — remove them before reporting the task done.
Run relevant verification stages based on the code modified. Agents must use good judgment to
select which tests to run based on which subsystem was changed. For instance, modifying
openair1 (PHY layer) usually means running physical layer simulation tests
(ctest -R '^physim\.' / phytest).
- Functional unit tests —
ctest -E '^physim\.|^benchmark_'inbuild/. - Isolated benchmarks —
ctest -R '^benchmark_'. Skip unless the change touches perf-sensitive code (PHY inner loops, RLC, scheduler). - Physim (phytest) —
ctest -R '^physim\.'. Essential when making changes toopenair1. Requires configuring with-DENABLE_PHYSIM_TESTS=ON(the executables build unconditionally regardless of that flag; 0 matched tests means the flag is missing — reconfigure and rerun, don't treat 0 as a pass). Full run is slow; for a fast pass across every physim executable, usectest -L quick_physim(well under 3 minutes) — good enough to catch a broken change quickly, but still not a substitute for the full set before release. - Affected CI test case — if the change affects RRC/NAS/PDU-session or rfsim behavior, run
the testcase through
ci-scripts.run_locally.shtakes a path to an XML testcase relative toci-scripts/. Build the required images first, then run:Rebuild the images after any code change before rerunning — Docker layer caching can silently serve a stale binary if only the final stage rebuilds.docker build . -f docker/Dockerfile.base.ubuntu -t ran-base docker build . -f docker/Dockerfile.build.ubuntu -t ran-build docker build . -f docker/Dockerfile.gNB.ubuntu -t oai-gnb docker build . -f docker/Dockerfile.nrUE.ubuntu -t oai-nr-ue docker build . -f docker/Dockerfile.nr-cuup.ubuntu -t oai-nr-cuup cd ci-scripts && ./run_locally.sh xml_files/container_5g_rfsim.xml
Lessons:
- An equivalence/regression test must call the real production functions, not re-derive the expected values independently — a self-consistent-but-wrong test can pass for a long time while the code under test is broken.
- Green unit tests don't mean the feature works end-to-end — verify live
(docker
ci-scriptsrun or manual rfsim below) before calling it done. - If a new feature fails, run the known-good baseline through the same path first to rule out an environment issue before debugging the feature.
- Hung process with no log output:
gdb -p <pid> -batch -ex 'thread apply all bt'beats another add-logging-and-rebuild cycle.
For interactive checks beyond the automated stages, run gNB and UE as plain host processes against a dockerized 5G core:
cd build
sudo ./nr-softmodem -O ../ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml -E --rfsim \
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.71.190 --gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 192.168.71.190
sudo ./nr-uesoftmodem -O ../ci-scripts/conf_files/nrue.uicc.yaml -E --rfsim -r 106 --numerology 1 -C 3319680000Present what you observe (RRC state, asserts, segfaults, "Bye." on shutdown) without declaring pass/fail yourself — that judgment call is the user's.
- Prefer adding new tests to
ctestwhen you write them. Agents should always try to generate unit tests for new features or bug fixes. - Agents must never post PR comments, create PRs, or push/update remote or upstream branches without explicit user instructions.
- Check
CONTRIBUTING.mdfor licensing/contribution requirements.