Compare commits

..

25 Commits

Author SHA1 Message Date
Guido Casati
8c11d04122 doc: update FEATURE_SET.md, 5Gnas.md, rrc-dev.md
- added Paging documentation
- updated to latest NGAP, F1AP, E1AP, NAS status
- fixed spelling errors

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
e20da28d53 Add useful log lines
- Add a LOG_I to 'nr_sdap_add_entity' to inform the user
  a SDAP entity is being created
- Add LOG_W to `nr_sdap_get_entity` to warn about
  empty SDAP entity list

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
cae92faaaa telnet: add UE context release request command
Add an RRC telnet command that sends a RAN-initiated NGAP UE Context Release
Request with a user-inactivity cause.

Register ctx_rel_req in the RRC telnet command table.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
744ee60d39 Paging UE (SDAP): reattach TUN after idle reset
UE paging can recreate the AS-side SDAP entity while NAS still keeps the
PDU session established. Per TS 38.304 clause 7.1 and TS 24.501 clauses
5.6.2.2.1/5.6.1.1, paging/service request restores user-plane resources
for an established PDU session, it does not imply deleting the UE IP/TUN
interface.

Deleting the UE TUN with SDAP entity teardown breaks user-plane continuity
after re-attach. We need SDAP entity lifetime and UE TUN lifetime to be
decoupled. This commit keeps a UE/PDU-session TUN registry outside the
SDAP entity lifetime. When a UE SDAP entity is recreated, reattach it
to the preserved TUN socket and restart the reader thread. On first PDU
session setup, NAS registers the TUN before attaching the reader.

The sequence is the following: (1) NAS register the iface
(2) sdap entity attaches to the iface (3) UE goes IDLE, SDAP
entity is destroyed, iface is deatched and brought down (4)
UE Service Request, SDAP entity is created (5) iface reattaches
to the SDAP entity and is brought up

UE reattach assumes the PDU session TUN interface was registered
before the SDAP entity is recreated.

DL/UL data is intentionally dropped when SDAP is not yet attached
or QFI is unavailable, rather than queued in this layer.

Changes:
- `nr_sdap.c`: keep a UE/PDU-session TUN registry, duplicate the stored
  socket into each SDAP entity, and add attach/detach/destroy helpers.
- `nr_sdap_entity.c`: detach SDAP entities from their TUN reader on
  deletion, preserve UE TUN interfaces across idle cleanup, and destroy
  gNB TUN interfaces when the gNB entity is removed. Drop downlink SDUs
  if the UE SDAP entity is not attached to a TUN socket yet.
- `openair3/NAS/NR_UE/nr_nas_msg.c`: set QFI before UE TUN creation so
  first attach can pick up cached QFI.
- `common/utils/tuntap_if.c`: add `tuntap_set_up`/`tuntap_set_down` helpers
  for UE interface state reflection and initialize `flags` in `tuntap_destroy`
  to avoid maybe-uninitialized build failures.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
75f10043fe Paging UE (MAC): monitor P-RNTI DCI only on PFs/POs in camped idle
Prior commits stored PCCH parameters and can decode P-RNTI,
this commit schedules PDCCH monitoring at the right TTIs.

In camped idle the UE must listen for network paging on P-RNTI only on
the correct paging frame (PF) and paging occasion (PO), only if the
paging common search space is set.

On monitor_paging_dci() success it adds P-RNTI to the downlink DCI
config for the existing PHY/MAC paging decode path.

Changes:
- Add monitor_paging_dci():
  - resolve paging_SS_id, call config_dci_pdu(TYPE_P_RNTI_) only
    when monitor_paging_dci() is true.
  - require is_ss_monitor_occasion on the paging search space
  - validate T/N/Ns from mac->paging_cfg
  - apply TS 38.304 §7.1 PF and i_s
  - PF via nr_pcch_sfn_is_pf
  - PO index i_s via nr_pcch_po_index
  - non-zero type-2 PO window via nr_pcch_type2_po_mo_in_range

Refs:
- 3GPP TS 38.304 §7.1 (PF/PO)
- 3GPP TS 38.213 §10.1 (PDCCH monitoring for paging)

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
f1fd36a22e Paging UE (RRC/MAC): preserve camped idle context
Keep normal no-redirection RRCRelease on the acquired
camped-cell context while preserving the existing full
GO_TO_IDLE cell-selection path for other idle transitions.

Changes:
- Add UE_IDLE and GO_TO_IDLE_KEEP_CAMPED to represent camped
  idle without starting RA.
- Map no-redirection RRCRelease to GO_TO_IDLE_KEEP_CAMPED and
  keep SIB1 validity for that path.
- Release connected-mode MAC/BWP0 dedicated config while
  preserving common BWP0 and paging PDCCH context.
- Keep the existing full GO_TO_IDLE cleanup for idle transitions
  that must perform cell selection.

Refs:
- TS 38.331 §5.3.11
- TS 38.304 §5.2.5, §5.2.6, §7.1
- TS 38.321 §5.12

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
57a365778e Paging UE (RRC/NAS): initial NAS UL transfer without SRB for paging
Route paging-triggered Service Request through NAS_INITIAL_UL_TRANSFER_REQ so
RRC can buffer the PDU for RRCSetupComplete (dedicatedNAS-Message, TS 38.331)
when no UL-DCCH SRB exists, start MAC RA from RRC_IDLE, or drop the ITTI PDU
with LOG_W if SRB1/SRB2 is already established (NAS paging path is 5GMM-IDLE
only).

Changes:
- Define ITTI NAS_INITIAL_UL_TRANSFER_REQ and
  NAS_INITIAL_UL_TRANSFER_REQ() (rrc_messages_def.h,
  rrc_messages_types.h).
- Add NR_MAC_RRC_START_RA, nr_rrc_mac_start_ra() (reset RA/MAC state,
  SRB0 Msg3 path), in config_ue.c, and dispatch in L2_interface_ue.c.
- Extend NR_UE_RRC_INST_t with pending_initial_nas for setup-complete
  transport (rrc_defs.h).
- Refactor ULInformationTransfer+PDCP send into
  nr_rrc_ue_send_ul_information_transfer_nas(): on NAS_UPLINK_DATA_REQ,
  refuse PDCP when neither SRB1 nor SRB2 is established (free PDU).
- On NAS_INITIAL_UL_TRANSFER_REQ: store NAS in pending_initial_nas when
  no SRB, in RRC_STATE_IDLE_NR set ra_trigger to RRC_CONNECTION_SETUP,
  call nr_rrc_ue_prepare_RRCSetupRequest(), and nr_rrc_send_msg_to_mac()
  with NR_MAC_RRC_START_RA, otherwise replace pending and send on SRB.
- Use forwarded initial NAS messafe in rrc_ue_generate_RRCSetupComplete():
  if pending_initial_nas is set, move it into the NAS payload and refresh
  security keys when integrity context exists, else generateRegistrationRequest().
- In nr_nas_msg.c, add send_nas_initial_ul_transfer_req() and use it for
  paging Service Request instead of send_nas_uplink_data_req()

Refs: TS 24.501, TS 38.331 §5.3.3.4, TS 33.501 §6.8.1.2

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
018b90bf07 Refactor UE (RRC/MAC): typed NR_MAC_RRC_START_RA for T300 and re-estab
RRC starts random access via NR_MAC_RRC_START_RA with an explicit
cause. RA trigger is no longer piggybacked on NR_MAC_RRC_CONFIG_RESET.
T300 expiry and RRC re-establishment are the call sites switched in this
commit. MAC handles setup/T300 and re-establishment paths in
nr_mac_start_ra().

Changes:
- Add nr_mac_rrc_types.h (nr_mac_ra_start_cause_t)
- Add nr_mac_rrc_start_ra_t in rrc_messages_types.h
- In rrc_UE.c, add nr_rrc_trigger_mac_ra(), call it from
  handle_t300_expiry and nr_rrc_initiate_rrcReestablishment
- In config_ue.c:
  - add nr_mac_start_ra() entry point with causes switch
  - add nr_rrc_mac_start_ra() handler
  - remove T300_EXPIRY, RE_ESTABLISHMENT reset handling
    in nr_rrc_mac_config_req_reset, now delegated to
    nr_mac_start_ra
- mac_defs.h: drop T300_EXPIRY from NR_UE_MAC_reset_cause_t

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
26c2724d47 Paging UE (RRC/NAS): trigger Service Request from UE paging
Transfer UE-side paging matches from RRC to NAS so a registered idle UE
can generate and send a Service Request after `NAS_PAGING_IND`. Guard
the path with explicit cause, identity, state, and mode checks so
unsupported cases are logged and ignored.

Changes:
- in `rrc_UE.c`, send `NAS_PAGING_IND` to TASK_NAS_NRUE with cause
  `AS_CONNECTION_ESTABLISH` from `rrc_nrue()` when a paging match is found
- in `nr_nas_msg.c`, implement `NAS_PAGING_IND` handling in `nas_nrue()`
- accept only paging indications with cause
  `AS_CONNECTION_ESTABLISH`, then require `nas->guti`,
  `FGS_REGISTERED`, and `FGS_IDLE` before proceeding
- generate the Service Request with `generateServiceRequest()` and send
  it through `send_nas_uplink_data_req()`

Refs:
- TS 23.502 §4.2.3.3 (Network Triggered Service Request)
- TS 24.501 §5.6.2.2.1 (Paging for 5GS services)

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
0b0873aecb Paging (RRC): handle PCCH in RRC
In NR RRC idle or inactive, decode PCCH SDUs from MAC and scan Paging
records (TS 38.331 §5.3.2.3) for ng-5G-S-TMSI against the UE M-TMSI
(lower 32 bits of fiveG_S_TMSI). PCCH is ignored in other states.

Changes:
- Add nr_rrc_ue_decode_pcch(): call nr_pcch_decode(), compare each
  ng-5G-S-TMSI M-TMSI to (fiveG_S_TMSI & UINT32_MAX), return on match
  or failure
- In rrc_nrue(), handle NR_RRC_MAC_PCCH_DATA_IND by wrapping sdu/
  sdu_size in byte_array_t, calling nr_rrc_ue_decode_pcch()

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
66932ea4bc Paging UE (MAC/PHY): forward PCCH to RRC and gate DLSCH on paging
Deliver MAC paging TB to RRC over ITTI, add a MAC flag
after an accepted P-RNTI DCI so the PHY IF can still invoke the DLSCH
path when ACK and HARQ indications do not line up.

Changes:
- Define NR_RRC_MAC_PCCH_DATA_IND, NRRrcMacPcchDataInd, and
  NR_RRC_MAC_PCCH_DATA_IND() for PCCH SDUs toward RRC.
- Add send_pcch_rrc() (main_ue_nr.c)
- Add pending_pcch_from_prnti to NR_UE_MAC_INST_t: set it in
  nr_ue_process_dci_dl_10() when P-RNTI DCI processing succeeds.
- In handle_dlsch(), call update_harq_status() only if the DL HARQ
  process for harq_pid is active (and not during RAR wait), and call
  nr_ue_send_sdu() when ack_nack is true or pending_pcch_from_prnti
  is set.
- In nr_ue_send_sdu() for FAPI_NR_RX_PDU_TYPE_DLSCH, treat the PDU as
  paging if DL config lists P_RNTI on a DLSCH PDU or the pending flag is
  set. On a valid successful decode, forward the TB with send_pcch_rrc()
  and clear the flag, otherwise keep the flag and skip normal MAC PDU
  parsing on that path.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
2b07f362e1 Paging UE (MAC): decode P-RNTI DCI 1_0 and build paging DL grant
Implement UE-side DCI format 1_0 for CRC scrambled by P-RNTI: decode the
P-RNTI-specific bitfield, validate the short message indicator,
compute the DL-SCH grant (TBS, TB scaling, fixed
RV/HARQ), and append the DL config PDU when the grant is accepted.

Changes:
- Add extract_10_p_rnti and call it from nr_extract_dci_00_10 for TYPE_P_RNTI_
  (replacing AssertFatal).
- In nr_ue_process_dci_dl_10: ignore dedicated pdsch_Config for TYPE_P_RNTI_,
  reject reserved SMIs that do not apply. After MCS apply
  nr_ue_process_dci_dl_10_p_rnti for TBS/Qm/code rate, RV/HARQ defaults,
  tb_scaling scaling factor, and guards. On success set bump the DLSCH DL
  config PDU count.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-04 20:37:55 +02:00
Guido Casati
d8c0e74925 Paging UE (MAC): harden DCI symbol parsing and configure P-RNTI in DCI PDU
Improve UE DCI PDU configuration robustness by validating monitoring-symbol
inputs before extraction, and add explicit P-RNTI DCI setup for paging
search-space monitoring.

Changes:
- Add guard checks for `monitoringSymbolsWithinSlot` presence, buffer, and
  minimum size before computing symbol masks in `config_dci_pdu()`
- Factor out monitoringSymbolsWithinSlot which is common across RNTI cases
  and reuse local `monitoringSymbols` pointer for symbol-mask extraction
- Implement `TYPE_P_RNTI_` branch to set symbol mask, `rel15->rnti =
  P_RNTI`, and `SubcarrierSpacing` for paging DCI configuration

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:25 +02:00
Guido Casati
b26b148c6e Paging UE (MAC): derive paging UE_ID from 5G-S-TMSI
Push the 5G-S-TMSI received by UE RRC down to MAC so paging can use
the TS 38.304 UE_ID.

Changes:
- add a paging UE_ID field to the UE MAC paging configuration
- add nr_rrc_mac_config_req_paging_ue_id() to derive UE_ID from
  5G-S-TMSI and store it under the MAC interface mutex
- update the NAS_5GMM_IND handling in rrc_nrue() to pass the received
  5G-S-TMSI to MAC for paging PF/PO derivation

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:25 +02:00
Guido Casati
f583354858 Paging UE (MAC): parse and store SIB1 PCCH config
Populate UE MAC paging state from SIB1 PCCH-Config so PF/PO-related
parameters are available to the rest of the UE MAC.

Changes:
- Add nr_ue_paging_cfg_t to NR_UE_MAC_INST_s with parsed paging fields
  (T, N, Ns, PF_offset, X) and the optional
  firstPDCCH-MonitoringOccasionOfPO list (first_mo_of_po[],
  first_mo_of_po_count)
- Add configure_pcch_config() to decode SIB1 PCCH-Config via the
  common helpers nr_pcch_default_paging_cycle_rf,
  nr_pcch_n_and_paging_frame_offset, nr_pcch_ns_per_pf and
  nr_pcch_first_pdcch_start_mo
- Add NR_PCCH_MAX_PO constant (TS 38.331 PCCH-Config) and size the
  first_mo_of_po[]
- Invoke configure_pcch_config() from nr_rrc_mac_config_req_sib1()

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:25 +02:00
Guido Casati
99720b6fbf Paging UE (PHY): handle P-RNTI DLSCH in UE RX indication path
Map P-RNTI scheduled DLSCH to the UE DLSCH receive indication flow so
paging traffic is also classified like DLSCH together with C-RNTI.

Changes:
- Set `dlsch0->rnti_type` from DLSCH RNTI in scheduled response, using
  `TYPE_P_RNTI_` when RNTI is `P_RNTI`
- Extend `nr_ue_dlsch_procedures()` RX indication mapping to include
  `TYPE_P_RNTI_` in the DLSCH indication case

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:25 +02:00
Guido Casati
c4248cc1e7 Paging (MAC): schedule PCCH in DL path at PF/PO
Move and extend PCCH transmission decisions into the MAC scheduler
so paging is only scheduled at matching UE paging occasions and
emitted as DL_TTI/TX_DATA PDUs for P-RNTI on the current frame/slot.

MAC scheduler dequeues from `pcch_queue` / `pcch_pending` and call
`schedule_nr_pcch()` at the UE’s paging occasion.

Paging occasion detection is now owned by MAC via PCCH scheduler
helper that implements PF/PO computation per TS 38.304
§7. Computation is determined by defaultPagingCycle (T),
nAndPagingFrameOffset (N), ns (Ns), with PF formula
(SFN + PF_offset) mod T = (T div N) * (UE_ID mod N),
and PO slot mapping for Ns = 1/2/4. Paging is transmitted only
when (frame, slot) is the UE's paging occasion
(TS 38.304 §7.1) and when a Type2-PDCCH CSS is configured via
pagingSearchSpace, so the UE can receive it.

The RRC PCCH path is simplified accordingly.

Changes

In `openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_pcch.c`:
- Add paging-specific scheduling logic, including `is_paging_occasion()`,
  paging-search-space resolution, and `nr_fill_nfapi_dl_PCCH_pdu()`
- Add `schedule_nr_pcch()` implementation to allocate CCE/PDSCH
  resources, populate DL/TX NFAPI requests, and pull PCCH SDU

In gNB scheduler:
- Invoke `schedule_nr_pcch()` in SA-mode DL scheduling

In `openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c`:
- Add PCCH scheduling helpers to be reused at UE side

Also:
- Register `openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_pcch.c` in
  `CMakeLists.txt` (`MAC_NR_SRC`)
- Remove no longer relevant `rrc_gNB_generate_pcch_msg()` from
  `openair2/RRC/NR/rrc_gNB.c`

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:25 +02:00
Guido Casati
dcfca23fed Paging (MAC): skip HARQ fields for P-RNTI DL DCI preparation
Ensure DL DCI payload preparation for paging with P-RNTI returns,
avoiding use of UE scheduling state and HARQ processes that do
not exist for paging.

Changes:
- Add early return in prepare_dci_dl_payload for TYPE_P_RNTI_
- Defer NR_UE_sched_ctrl_t lookup until after the P-RNTI path to avoid
accessing UE context and HARQ state for paging

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:11 +02:00
Guido Casati
7956860e9d Paging (F1AP/MAC): enqueue PCCH SDUs in MAC from F1AP paging
When the core pages an idle UE, the DU must hold the RRC Paging message until
MAC can send it on PCCH at the right paging occasion. This commit moves that
buffering into gNB MAC and connects the existing F1AP Paging entry points.

The CN UE paging is therefore routed from F1AP inputs into a MAC-managed
PCCH queue. The unused RRC PCCH generator stub is dropped. This makes paging
delivery path explicit in MAC for later PF/PO scheduling.

Changes:
- In `DU_handle_Paging` (`f1ap_du_paging.c`), decode paging and call
  `nr_mac_pcch_enqueue(instance, tmsi, ue_id)` for CN UE identity.
- MAC (`gNB_scheduler_pcch.c`, new): buffer paging messages until the scheduler
  can transmit them - encode with `do_NR_Paging()`, queue up to 16 SDUs in
  `spsc_q`, hold the active head in `pcch_pending`, init/teardown with the
  gNB MAC instance
- Add `nr_mac_pcch_item_t` and `pcch_queue` storage to MAC common
  channel structs in `nr_mac_gNB.h`.
- In `f1_paging_transfer_direct` (`mac_rrc_dl_direct.c`), validate CN UE
  identity and enqueue paging to MAC. It rejects unsupported RAN UE identity.
- Remove obsolete `rrc_gNB_generate_pcch_msg` declaration and stub from
  `nr_rrc_proto.h` and `rrc_gNB.c`.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:02:09 +02:00
Guido Casati
b9d57a53eb Paging UE (RRC/ASN): decode Paging
Add PCCH decoded and use in ASN.1 tests.

Changes:
- add `nr_pcch_decode()`
- extend `test_asn1_msg.cpp` with `encode_decode_paging()` round trips
  for multiple `ng-5G-S-TMSI` values, `accessType`, and `fullI-RNTI`

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:01:43 +02:00
Guido Casati
dda4014f51 Paging (RRC/ASN): refactor do_NR_Paging and extend UE identity support
Replace the old buffer-based do_NR_Paging API with a params struct and
byte_array_t return; add support for fullI-RNTI and optional accessType/
pagingCause. Encoding uses uper_encode_to_new_buffer, callers own and
free the returned buffer.

Changes:
- asn1_msg.h:
  - Add nr_paging_params_t (ue_identity_type, union ue_identity union
    { m_tmsi or full_i_rnti }, access_type, paging_cause),
  - Add NR_PAGING_FULL_I_RNTI_SIZE define.
- asn1_msg.c:
  - Implement do_NR_Paging with nr_paging_params_t.
  - Support ng-5G-S-TMSI (48-bit, M-TMSI in bytes 2–5)
    and fullI-RNTI (40-bit, 5 bytes).
  - Set optional accessType (non3GPP) and optional nonCriticalExtension
    (pagingRecordList-v1700 with pagingCause-r17).
  - Use asn1cCalloc for ASN.1 allocations and encode via
    uper_encode_to_new_buffer. On failure free buffer and return empty
    byte_array_t.
- rrc_gNB.c: disable do_NR_Paging call in rrc_gNB_generate_pcch_msg
  with #if 0 (will be removed in a descendant commit, no need to update
  call site yet).
- test_asn1_msg.cpp: update caller in asn1 tests (minimal change, test
  will be updated in a later commit)

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-03 18:01:43 +02:00
Guido Casati
2caf201eed MAC gNB: move RB/MCS/TBS selection helper for common PDSCH to scheduler primitives
Expose the RB/MCS/TBS selection helper as a shared MAC function for
common PDSCH instead of keeping as static variant for SIB-specific use
in the BCH scheduler. It will be reused by the PCCH code path in a descendant
commit.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-01 10:29:19 +02:00
Guido Casati
e1422361a9 MAC gNB: implement and use is_type0_occasion()
Implement the Type0-PDCCH occasion helper for reusability and
use it in schedule_nr_sib1, and adopt in a descendant commit
in PCCH scheduling as well.

Changes:
- gNB_scheduler_primitives.c: add is_type0_occasion()
- gNB_scheduler_bch.c: in schedule_nr_sib1, replace inline code
  with is_type0_occasion
- Rename check_frame_sib1 to check_frame_type0, as it is not
  limited to sib1 but applies to PCCH as well.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-01 10:29:19 +02:00
Guido Casati
7668ac4071 MAC gNB: use get_max_ssbs() in BCH scheduler
gNB_scheduler_bch.c now calls the shared get_max_ssbs() instead of
duplicating the SSB bitmap size logic in schedule_nr_sib1

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-01 10:29:18 +02:00
Guido Casati
0f02d94f6c MAC gNB: move SSB/Type0-PDCCH helpers from BCH to scheduler primitives
Move get_max_ssbs and the Type0-PDCCH frame-check logic from
gNB_scheduler_bch.c to gNB_scheduler_primitives.c so they can be
reused (e.g. for both paging and SIB1).

Changes:
- check_frame_sib1() with NULL check for ssb_periodicityServingCell
  and clearer logic
- Improved documentation

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
2026-06-01 10:29:18 +02:00
327 changed files with 8006 additions and 14839 deletions

View File

@@ -5,4 +5,3 @@ common/utils/T/T_IDs.h
common/utils/T/T_messages.txt.h
common/utils/T/genids
common/utils/T/genids.o
build/

View File

@@ -1,190 +0,0 @@
name: Duranta Jenkins Dispatch
on:
pull_request_target:
types: [opened, synchronize, reopened, labeled]
branches: [develop]
push:
branches:
- develop
concurrency:
group: ${{ github.event_name }}-${{ github.event.action }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
jobs:
verify-signed-commits:
runs-on: ubuntu-24.04
if: github.event_name == 'pull_request_target'
steps:
- name: Check all commits are signed
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
UNSIGNED=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits \
--paginate --jq '[.[] | select(.commit.verification.verified == false) | .sha[:7]] | join(", ")')
if [ -n "$UNSIGNED" ]; then
echo -e "$UNSIGNED commits are missing signature"
gh pr comment ${{ github.event.pull_request.number }} --repo ${{ github.repository }} --body "$(cat <<EOF
**Validation:**
The following commit(s) are missing signature:
$UNSIGNED
Please use 'git commit -S' to sign your commits.
For detailed instructions, refer to the [CONTRIBUTING.md](https://github.com/duranta-project/openairinterface5g/blob/develop/CONTRIBUTING.md) file at the root of this repository or [GitHub Docs](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)
EOF
)"
exit 1
fi
check-labels:
needs: verify-signed-commits
runs-on: ubuntu-24.04
if: github.event_name == 'pull_request_target'
steps:
- name: Check for mandatory CI label
run: |
PR_LABELS=$(echo '${{ toJson(github.event.pull_request.labels) }}' | jq -r '.[].name')
for label in \
"${{ vars.BUILD_ONLY_LABEL }}" \
"${{ vars.DOC_LABEL }}" \
"${{ vars.NR_LABEL }}" \
"${{ vars.NRUE_LABEL }}" \
"${{ vars.LTE_LABEL }}" \
"${{ vars.CI_LABEL }}" \
"${{ vars.RETRIGGER_CI_LABEL }}"; do
if echo "$PR_LABELS" | grep -qxF "$label"; then
exit 0
fi
done
exit 1
detect-changes:
needs: check-labels
runs-on: ubuntu-24.04
if: |
always() && (
github.event_name == 'push' ||
needs.check-labels.result == 'success'
) && (
github.event.action != 'labeled' ||
github.event.label.name == vars.RETRIGGER_CI_LABEL
)
outputs:
protected_files_changed: ${{ steps.filter.outputs.protected }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check changed files
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
protected:
- 'ci-scripts/**'
- '.github/workflows/**'
- '.github/actions/**'
- 'docker/**'
- 'charts/**'
- 'openshift/**'
- 'cmake_targets/build_oai'
- 'cmake_targets/tools/build_helper'
require-maintainer-approval:
needs: detect-changes
if: |
always() &&
needs.detect-changes.outputs.protected_files_changed == 'true'
runs-on: ubuntu-24.04
environment:
name: ci-approval
steps:
- run: echo "Maintainer has approved the changes"
trigger-jenkins:
needs:
- check-labels
- detect-changes
- require-maintainer-approval
if: |
always() &&
(
needs.detect-changes.outputs.protected_files_changed == 'false' ||
needs.require-maintainer-approval.result == 'success'
)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}
- name: Trigger Jenkins
run: |
# Write payload to a temp file to avoid shell escaping issues
cat << 'EOF' > /tmp/payload.json
${{ toJson(github.event) }}
EOF
# Filter and send
jq -c 'del(.pull_request.body)' /tmp/payload.json > /tmp/filtered_payload.json
# Remap pull_request_target -> pull_request for Jenkins compatibility
EVENT_NAME="${{ github.event_name }}"
if [ "$EVENT_NAME" = "pull_request_target" ]; then
EVENT_NAME="pull_request"
fi
curl -X POST "https://${{ secrets.J_USER }}:${{ secrets.J_PASS }}@${{ secrets.J_URL }}" \
-H "Accept: */*" \
-H "Content-Type: application/json" \
-H "User-Agent: GitHub-Hookshot/${{ secrets.H_AGENT }}" \
-H "X-Github-Delivery: ${{ secrets.GITHUB_TOKEN }}" \
-H "X-Github-Event: $EVENT_NAME" \
-H "X-Github-Hook-Id: ${{ secrets.H_ID }}" \
-H "X-Github-Hook-Installation-Target-Id: ${{ secrets.H_TARGET }}" \
-H "X-Github-Hook-Installation-Target-Type: repository" \
--data @/tmp/filtered_payload.json
cleanup:
needs:
- verify-signed-commits
- check-labels
- detect-changes
- require-maintainer-approval
- trigger-jenkins
if: always() && github.event_name == 'pull_request_target'
runs-on: ubuntu-24.04
steps:
- name: Remove retrigger-ci label
run: |
PR_LABELS=$(echo '${{ toJson(github.event.pull_request.labels) }}' | jq -r '.[].name')
if echo "$PR_LABELS" | grep -qxF "${{ vars.RETRIGGER_CI_LABEL }}"; then
gh pr edit ${{ github.event.pull_request.number }} --remove-label "${{ vars.RETRIGGER_CI_LABEL }}" --repo ${{ github.repository }}
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -2,7 +2,7 @@
# RELEASE NOTES: #
## [v2.4.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v2.4.0) -> December 2025. ##
## [v2.4.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.4.0) -> December 2025. ##
General new features and improvements (both RAN and UE):
- Rework LDPC BBdev/AAL interface and support both AMD T2/Intel vRAN Boost
@@ -68,7 +68,7 @@ Configuration file changes:
should be removed
- `MACRLCs.[0].stats_max_ue` has been added
## [v2.3.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v2.3.0) -> July 2025. ##
## [v2.3.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.3.0) -> July 2025. ##
General new features and improvements (both RAN and UE):
- Preliminary support for RedCap UEs
@@ -114,7 +114,7 @@ nrUE changes:
Regression:
- Multiple BWPs do not work reliably on gNB; use tag 2025.w17
## [v2.2.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v2.2.0) -> November 2024. ##
## [v2.2.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.2.0) -> November 2024. ##
General 5G improvements (both gNB and UE):
- Make standalone mode (SA) the default (see [`RUNMODEM.md`](doc/RUNMODEM.md))
@@ -170,7 +170,7 @@ General 5G improvements (both gNB and UE):
This release also includes many fixes and documentation updates. See
`doc/README.md` in the repository for an overview of documentation.
## [v2.1.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v2.1.0) -> February 2024. ##
## [v2.1.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.1.0) -> February 2024. ##
This release improves existing 5G support and adds various new features.
@@ -197,7 +197,7 @@ interoperability is under testing.
This release also includes many fixes and documentation updates.
## [v2.0.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v2.0.0) -> August 2023. ##
## [v2.0.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.0.0) -> August 2023. ##
This release adds support for 5G and maintains previous features:
* 5G SA in gNB
@@ -226,11 +226,11 @@ This release adds support for 5G and maintains previous features:
For more information on supported features, please refer to the [feature set](doc/FEATURE_SET.md).
## [v1.2.1](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.2.1) -> February 2020. ##
## [v1.2.1](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.2.1) -> February 2020. ##
* Bug fix for mutex lock for wake-up signal
## [v1.2.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.2.0) -> January 2020. ##
## [v1.2.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.2.0) -> January 2020. ##
This version adds the following implemented features:
@@ -246,11 +246,11 @@ This version also has an improved code quality:
* Better Test Coverage in Continuous Integration:
- Initial framework to do long-run testing at R2LAB
## [v1.1.1](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.1.1) -> November 2019. ##
## [v1.1.1](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.1.1) -> November 2019. ##
- Bug fix in the TDD Fair Round-Robin scheduler
## [v1.1.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.1.0) -> July 2019. ##
## [v1.1.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.1.0) -> July 2019. ##
This version adds the following implemented features:
@@ -282,19 +282,19 @@ This version has an improved code quality:
- Multi-RRU TDD mode
- X2 Handover in FDD mode
## [v1.0.3](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.0.3) -> June 2019. ##
## [v1.0.3](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.3) -> June 2019. ##
- Bug fix for LimeSuite v19.04.0 API
## [v1.0.2](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.0.2) -> February 2019. ##
## [v1.0.2](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.2) -> February 2019. ##
- Full OAI support for 3.13.1 UHD
## [v1.0.1](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.0.1) -> February 2019. ##
## [v1.0.1](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.1) -> February 2019. ##
- Bug fix for the UE L1 simulator.
## [v1.0.0](https://github.com/duranta-project/openairinterface5g/releases/tag/v1.0.0) -> January 2019. ##
## [v1.0.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v1.0.0) -> January 2019. ##
This version first implements the architectural split described in the following picture.

View File

@@ -383,12 +383,6 @@ endif()
add_boolean_option(ENABLE_IMSCOPE OFF "Enable phy scope based on imgui" OFF)
add_boolean_option(ENABLE_IMSCOPE_RECORD OFF "Enable recording IQ data for imscope" OFF)
#########################
##### E3 AGENT
#########################
set(E3_AGENT "OFF" CACHE STRING "O-RAN nGRG E3 Agent for dApps")
set_property(CACHE E3_AGENT PROPERTY STRINGS "ON" "OFF")
##################################################
# ASN.1 grammar C code generation & dependencies #
##################################################
@@ -861,6 +855,7 @@ set(NR_PHY_SRC_RU
${OPENAIR1_DIR}/PHY/MODULATION/nr_beamforming.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/INIT/nr_init_ru.c
${OPENAIR1_DIR}/PHY/if4_tools.c
)
set(PHY_SRC_UE
@@ -929,6 +924,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -1774,25 +1770,23 @@ target_link_libraries(lte-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs
# force the generation of ASN.1 so that we don't need to wait during the build
target_link_libraries(lte-uesoftmodem PRIVATE
asn1_lte_rrc asn1_s1ap asn1_m2ap asn1_m3ap asn1_x2ap)
# nr RRU
add_executable(nr-oru
${OPENAIR_DIR}/executables/nr-ru.c
${OPENAIR_DIR}/openair1/PHY/INIT/nr_parms.c
${OPENAIR_DIR}/openair1/SCHED_NR/phy_frame_config_nr.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_prach_procedures.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_ru_procedures.c
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
${OPENAIR_DIR}/executables/main_nr_ru.c
)
target_link_libraries(nr-oru PRIVATE
UTIL NR_PHY_RU PHY_NR shlib_loader dl
radio_common softmodem_common nfapi_pnf_lib)
target_link_libraries(nr-oru PRIVATE pthread m CONFIG_LIB rt ${T_LIB} utils
barrier actor nfapi_user_lib)
target_link_libraries(nr-oru PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_phy_common time_management)
if (OAI_RU_FRONTHAUL)
add_executable(nr-oru
${OPENAIR_DIR}/executables/nr-ru.c
${OPENAIR_DIR}/openair1/PHY/INIT/nr_parms.c
${OPENAIR_DIR}/openair1/SCHED_NR/phy_frame_config_nr.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_prach_procedures.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_ru_procedures.c
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
${OPENAIR_DIR}/executables/main_nr_ru.c
${OPENAIR_DIR}/executables/nr-oru.c
)
target_link_libraries(nr-oru PRIVATE
UTIL NR_PHY_RU PHY_NR shlib_loader dl oru_fh MAC_NR_COMMON
radio_common softmodem_common nfapi_pnf_lib)
target_link_libraries(nr-oru PRIVATE pthread m CONFIG_LIB rt ${T_LIB} utils
barrier actor nfapi_user_lib)
target_link_libraries(nr-oru PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_phy_common time_management)
endif()
# nr-softmodem
###################################################
@@ -1837,11 +1831,6 @@ if(E2_AGENT)
target_compile_definitions(nr-softmodem PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
endif()
if (E3_AGENT)
target_link_libraries(nr-softmodem PRIVATE e3ap)
target_compile_definitions(nr-softmodem PRIVATE E3_AGENT)
endif()
# force the generation of ASN.1 so that we don't need to wait during the build
target_link_libraries(nr-softmodem PRIVATE

View File

@@ -1,47 +1,68 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
# Contributing to Duranta
# Contributing to OpenAirInterface
We want to make contributing to this project as easy and transparent as possible.
1. Create an account on [GitHub](https://github.com/). Only contributions
against [`duranta-project/openairinterface5g/`](https://github.com/duranta-project/openairinterface5g/)
are accepted.
2. Fork the repository, and open pull requests for your contributions from your
fork.
3. The contributing policies are described in the [corresponding documentation
Please refer to the steps described on our website: [How to contribute to OAI](https://www.openairinterface.org/?page_id=112).
1. Sign and return a Contributor License Agreement to OAI team.
2. Register on [Eurecom GitLab Server](https://gitlab.eurecom.fr/users/sign_up)
if you do not have any.
- We recommend that you register with a professional or student email address.
- If your email domain (`@domain.com`) is not whitelisted, please contact us
(mailto:oaicicdteam@openairinterface.org).
- Eurecom GitLab does NOT accept public email domains.
3. Provide the OAI team with the **username** of this account to
(mailto:oaicicdteam@openairinterface.org) ; we will give you the developer
rights on this repository.
4. The contributing policies are described in the [corresponding documentation
page](doc/code-style-contrib.md).
4. [Sign the CLA](https://github.com/duranta-project/governance/blob/main/docs/easy_cla_process.md)
either before doing making your first pull request or after submitting the
pull request.
- PLEASE DO NOT FORK the OAI repository on your own Eurecom GitLab account.
It just eats up space on our servers.
- You can fork onto another hosting system. But we will NOT accept a merge
request from a forked repository.
* This decision was made for the license reasons.
* The Continuous Integration will reject your merge request.
5. Mandatory signing of all the commits using the email address used for CLA.
## Commit Guidelines
Every pull request must pass two CI checks before it can be merged:
1. **[Developer Certificate of Origin (DCO)](https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin)**:
Each commit must include a `Signed-off-by:` trailer in the commit message.
Use `git commit -s` (or `--signoff`).
2. **[Verified commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)**:
Each commit must be cryptographically signed using SSH or GPG keys to confirm
its origin.
### Signing Commits
GitHub supports commit signing using either SSH keys or GPG keys. For the
step-by-step setup (key generation, Git configuration, registering the key on
GitHub, and verifying signatures locally), see the
[commit signing section of the Git guide](doc/git-guide.md#setting-up-commit-signing).
To sign commits:
You can also get the verified label
on your commits via using [SSH KEYS or GPG KEYS](https://docs.gitlab.com/user/project/repository/signed_commits/)
```
# Edit .git/config in the git repository you are working on
# Add the user section
[user]
name = YOUR NAME
email = YOUR EMAIL ADDRESS
# If you use a signing key, use the below configuration instead
[user]
name = YOUR NAME
email = YOUR EMAIL ADDRESS
signingkey = LOCATION OF SSH KEYS or GPG KEY
[gpg]
format = ssh
[commit]
gpgsign = true
```
> **NOTE:** If your commits are not signed the CI framework will not accept the MR.
> **NOTE:** If your commits are not signed, the CI framework will not accept the PR.
For more information regarding contribution guidelines
please check [this document](doc/code-style-contrib.md)
## License
By contributing to Duranta, you agree that your contributions will be
By contributing to OpenAirInterface, you agree that your contributions will be
licensed under
1. [CSSL v1.0 license](LICENSES/preferred/CSSL-v1.0.txt): for RAN and UE

View File

@@ -1,21 +1,25 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
<h1 align="center">
<a href="https://lfnetworking.org/projects/duranta/"><img src="https://raw.githubusercontent.com/duranta-project/governance/main/logos/Duranta-Logo-Color.png" alt="Duranta OAI" width="550"></a>
<a href="https://openairinterface.org/"><img src="https://openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png" alt="OAI" width="550"></a>
</h1>
<p align="center">
<a href="https://github.com/duranta-project/openairinterface5g/blob/develop/LICENSE"><img src="https://img.shields.io/badge/license-CSSL--v1.0-blue" alt="License"></a>
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-CSSL--v1.0-blue" alt="License"></a>
<a href="https://releases.ubuntu.com/22.04/"><img src="https://img.shields.io/badge/OS-Ubuntu22-Green" alt="Supported OS Ubuntu 22"></a>
<a href="https://releases.ubuntu.com/24.04/"><img src="https://img.shields.io/badge/OS-Ubuntu24-Green" alt="Supported OS Ubuntu 24"></a>
<a href="https://releases.ubuntu.com/26.04/"><img src="https://img.shields.io/badge/OS-Ubuntu26-Green" alt="Supported OS Ubuntu 26"></a>
<a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux"><img src="https://img.shields.io/badge/OS-RHEL9-Green" alt="Supported OS RHEL9"></a>
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedora44-Green" alt="Supported OS Fedora 44"></a>
<a href="https://getfedora.org/en/workstation/"><img src="https://img.shields.io/badge/OS-Fedore44-Green" alt="Supported OS Fedora 44"></a>
</p>
<p align="center">
<a href="https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-Image-Builder/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-Ubuntu-Image-Builder%2F&label=build-Ubuntu-x86%20Images"></a>
<a href="https://jenkins-oai.eurecom.fr/job/RAN-RHEL-Cluster-Image-Builder/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-RHEL-Cluster-Image-Builder%2F&label=build-RHEL-Cluster%20Images"></a>
<a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/releases"><img alt="GitLab Release (custom instance)" src="https://img.shields.io/gitlab/v/release/oai/openairinterface5g?gitlab_url=https%3A%2F%2Fgitlab.eurecom.fr&include_prereleases&sort=semver"></a>
</p>
<p align="center">
<a href="https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-Ubuntu18-Image-Builder%2F&label=build-Ubuntu-x86%20Images"></a>
<a href="https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-RHEL8-Cluster-Image-Builder%2F&label=build-UBI-x86%20Images"></a>
<a href="https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-ARM-Image-Builder/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FRAN-Ubuntu-ARM-Image-Builder%2F&label=build-Ubuntu-ARM%20Images"></a>
</p>
@@ -27,23 +31,14 @@
<a href="https://hub.docker.com/r/oaisoftwarealliance/oai-nr-cuup"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/oaisoftwarealliance/oai-nr-cuup?label=NR-CUUP%20docker%20pulls"></a>
</p>
# Duranta - OpenAirInterface
Duranta OpenAirInterface RAN delivers and maintains an open-source cellular
wireless software stack for 4G, 5G and future networking technologies. It
supports simulation, prototyping, and end-to-end deployments on
Commercial-Off-The-Shelf (COTS) hardware. Built for research and
experimentation, it provides standard-compliant interfaces and is released
under the Collaborative Standards Software License (CSSL).
## License
# OpenAirInterface License #
* [OAI License Model](http://www.openairinterface.org/?page_id=101)
* [CSSL v1.0](http://www.openairinterface.org/?page_id=698)
The source code is distributed under [**CSSL v1.0**](LICENSE).
Some files, such as for orchestration, are distributed under
[MIT license](./LICENSES/preferred/MIT.txt). Documentation is distributed under
[MIT license](preferred)(MIT.txt). Documentation is distributed under
[Creative Commons Attribution 4.0 International license](LICENSES/preferred/CC-BY-4.0.txt).
All the files without an explicit copyright header have an implicit "Copyright
@@ -59,7 +54,7 @@ history:
3. OAI Public License v1.0: starting tag v.04 till v1.0
4. GPL 3: starting tag v.0 till v.04 (only initial implementation of 4G)
## Where to Start
# Where to Start #
* [General overview of documentation](./doc/README.md)
* [The implemented features](./doc/FEATURE_SET.md)
@@ -75,7 +70,7 @@ To find all READMEs, this command might be handy:
find . -iname "readme*"
```
## RAN repository structure
# RAN repository structure #
The OpenAirInterface (OAI) software is composed of the following parts:
@@ -100,9 +95,9 @@ openairinterface5g
└── tools : Tools for use by the developers/ci machines: code analysis and formatting
```
## How to get support from the Community
# How to get support from the OAI Community #
You can ask your question on the [mailing lists](https://github.com/duranta-project/openairinterface5g/wiki/MailingList).
You can ask your question on the [mailing lists](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/MailingList).
Your email should contain below information:
@@ -113,6 +108,6 @@ Your email should contain below information:
- OAI gNB/DU/CU/CU-CP/CU-UP configuration file in `.conf` format only.
- Logs of OAI gNB/DU/CU/CU-CP/CU-UP in `.log` or `.txt` format only.
- In case your question is related to performance, include a small description of the machine (Operating System, Kernel version, CPU, RAM and networking card) and diagram of your testing environment.
- Known/open issues are present on [Github](https://github.com/duranta-project/openairinterface5g/issues), so keep checking.
- Known/open issues are present on [GitLab](https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues), so keep checking.
Always remember a structured email will help us understand your issues quickly.

View File

@@ -1,61 +0,0 @@
# Duranta-OpenAirInterface Roadmap
## RAN Roadmap
### Q2 2026
- GPU LDPC Accelerator
- NR-DC Support
- CN Paging procedures
- Support for 64 UEs with E2E throughput validation
- Basic Cat-A OAI O-RU (simulated radio)
### Q3 2026
- QoS-enforcing scheduler
- Xn Handover Support
- UL MU-MIMO
- Aperiodic UL channels (SRS/CSI reporting)
- NR user plane protocol
- Multi-cell support in L2
- Support for 128 UEs with E2E throughput validation
### Q4 2026
- Cat-B Support for FHI 7.2 at RU/DU
- RAN Paging
- Support of 5G RAN Slicing
- Multi-cell performance evaluation (with at-least 3 cells)
### Q1 2027
- Digital Beamforming Support
- DL MU-MIMO at L1
---
## UE Roadmap
### Q2 2026
- Support for Handover Procedures
- Basic Sidelink Procedures (PSSCH, PSCCH)
- PUCCH formats 1&3
### Q3 2026
- Support for 2 UL layers
- Support for 2 DL layers
- RU sharing
### Q4 2026
- Reduce feedback time
- AT command interface
- DL KPI Improvements
- UL KPI Improvements
### Q1 2027
- Scan carrier
- Power control procedures for outdoor operation

View File

@@ -14,7 +14,7 @@ description: A Helm chart for physical simulators network function
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: https://raw.githubusercontent.com/duranta-project/governance/main/logos/Duranta-Logo-Color.png
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
@@ -31,8 +31,8 @@ keywords:
- 5G
sources:
- https://github.com/duranta-project/openairinterface5g
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: oaicicdteam@openairinterface.org
email: contact@openairinterface.org

View File

@@ -14,7 +14,7 @@ description: A Helm subchart for 4G physims network function
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: https://raw.githubusercontent.com/duranta-project/governance/main/logos/Duranta-Logo-Color.png
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
@@ -30,8 +30,8 @@ keywords:
- 4G
sources:
- https://github.com/duranta-project/openairinterface5g
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: oaicicdteam@openairinterface.org
email: contact@openairinterface.org

View File

@@ -14,7 +14,7 @@ description: A Helm chart for physical simulators network function
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: https://raw.githubusercontent.com/duranta-project/governance/main/logos/Duranta-Logo-Color.png
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
@@ -31,8 +31,8 @@ keywords:
- 5G
sources:
- https://github.com/duranta-project/openairinterface5g
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: oaicicdteam@openairinterface.org
email: contact@openairinterface.org

View File

@@ -14,7 +14,7 @@ description: A Helm subchart for 5G physims network function
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
icon: https://raw.githubusercontent.com/duranta-project/governance/main/logos/Duranta-Logo-Color.png
icon: http://www.openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
@@ -30,8 +30,8 @@ keywords:
- 5G
sources:
- https://github.com/duranta-project/openairinterface5g
- https://gitlab.eurecom.fr/oai/openairinterface5g
maintainers:
- name: OPENAIRINTERFACE
email: oaicicdteam@openairinterface.org
email: contact@openairinterface.org

View File

@@ -3,12 +3,6 @@
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
import groovy.transform.Field
@Field def branch = ''
@Field def gitLocalBranch = ''
@Field def downstreamResults = [:]
// Location of the executor node
def nodeExecutor = params.nodeExecutor
@@ -18,43 +12,13 @@ def do4Gtest = false
def do5Gtest = false
def do5GUeTest = false
//
def gitCommitAuthorEmailAddr
// list of failing stages
def failingStages = ""
def mrValidationWarning = ""
// Globally scoped status result variables for downstream jobs.
def ubuntuBuildStatus = ''
def ubuntuArmBuildStatus = ''
def ubuntuJetsonBuildStatus = ''
def rhelBuildStatus = ''
def armBuildStatus = ''
def physim5GStatus = ''
def physimGH5GStatus = ''
def channelSimStatus = ''
def vrtSim5GStatus = ''
def rfSim5GStatus = ''
def flexricRAN5GStatus = ''
def physim4GStatus = ''
def rfSim4GStatus = ''
def l2Sim4GStatus = ''
def lteTDDB200Status = ''
def lteFDDB200OAIUEStatus = ''
def lteFDDB200Status = ''
def lteTDD2x2N3xxStatus = ''
def nsaTDDB200Status = ''
def saTDDB200Status = ''
def phytestLDPCoffloadStatus = ''
def saAW2SStatus = ''
def saAERIALStatus = ''
def saMultiAntennaStatus = ''
def saFHI72Status = ''
def saFHI72MplaneStatus = ''
def saHandoverStatus = ''
def saAERIALOAIUEStatus = ''
def saOAIUEStatus = ''
OAI_Registry = "gracehopper3-oai.sboai.cs.eurecom.fr"
pipeline {
agent {
@@ -62,100 +26,77 @@ pipeline {
}
options {
timestamps()
gitLabConnection('OAI GitLab')
ansiColor('xterm')
}
stages {
stage ("Get Parameters") {
stage ("Verify Parameters") {
steps {
script {
echo '\u2705 \u001B[32mGet Parameters\u001B[0m'
// GIT_BRANCH is prefixed with "origin/" by Jenkins - stripped version for use in tags and params in case of PUSH event
gitLocalBranch = env.GIT_BRANCH.replace('origin/', '')
if (env.GITHUB_PR_NUMBER) {
echo "PR number : ${env.GITHUB_PR_NUMBER}"
echo "Source Repository : ${env.GITHUB_PR_URL}"
echo "Source Branch : ${env.GITHUB_PR_SOURCE_BRANCH}"
echo "Commit ID : ${env.GITHUB_PR_HEAD_SHA}"
echo "Target Repo : ${env.GIT_URL}"
echo "Target Branch : ${env.GITHUB_PR_TARGET_BRANCH}"
echo "Label : ${env.GITHUB_PR_LABELS}"
branch = "${env.GITHUB_PR_SOURCE_BRANCH.replace('/', '-').replace('+', '-')}-${env.GITHUB_PR_HEAD_SHA}"
} else {
echo "Branch : ${gitLocalBranch}"
echo "Commit ID : ${env.GIT_COMMIT}"
branch = "${gitLocalBranch}-${env.GIT_COMMIT}"
}
env.JOB_TIMESTAMP = sh(returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"').trim()
}
}
}
stage ("Verify Labels") {
steps {
echo '\u2705 \u001B[32mVerify Labels\u001B[0m'
script {
if (env.GITHUB_PR_NUMBER) {
if (!(env.GITHUB_PR_LABELS)) {
def gitBaseUrl = env.GIT_URL.trim().replace('.git', '')
def message = "**CI Build:** [#${env.BUILD_NUMBER}](${BUILD_URL}) | Not performing CI due to the absence of one of the following mandatory labels:\n"
message += "- ${gitBaseUrl}/labels/documentation (don't perform any stages)\n"
message += "- ${gitBaseUrl}/labels/BUILD-ONLY (execute only build stages)\n"
message += "- ${gitBaseUrl}/labels/4G-LTE (perform 4G tests)\n"
message += "- ${gitBaseUrl}/labels/5G-NR (perform 5G tests)\n"
message += "- ${gitBaseUrl}/labels/nrUE (perform only 5G-UE related tests including physims excluding LDPC tests)\n"
message += "- ${gitBaseUrl}/labels/CI (perform both 4G and 5G tests)\n"
githubPRComment comment: githubPRMessage(message)
error('Not performing CI due to lack of mandatory labels')
}
if (env.GITHUB_PR_LABELS.contains('CI')) {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true
echo '\u2705 \u001B[32mVerify Labels\u001B[0m'
if ("MERGE".equals(env.gitlabActionType)) {
LABEL_CHECK = sh returnStdout: true, script: 'ci-scripts/checkGitLabMergeRequestLabels.sh --mr-id ' + env.gitlabMergeRequestIid
LABEL_CHECK = LABEL_CHECK.trim()
if (LABEL_CHECK == 'NONE') {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Your merge request should have one of the mandatory labels:\n\n"
message += " - ~documentation (don't perform any stages)\n"
message += " - ~BUILD-ONLY (execute only build stages)\n"
message += " - ~4G-LTE (perform 4G tests)\n"
message += " - ~5G-NR (perform 5G tests)\n"
message += " - ~CI (perform both 4G and 5G tests)\n"
message += " - ~nrUE (perform only 5G-UE related tests including physims excluding LDPC tests)\n\n"
message += "Not performing CI due to lack of labels"
addGitLabMRComment comment: message
error('Not performing CI due to lack of labels')
} else if (LABEL_CHECK == 'FULL') {
do4Gtest = true
do5Gtest = true
do5GUeTest = true
}
if (env.GITHUB_PR_LABELS.contains('4G-LTE')) {
} else if (LABEL_CHECK == "SHORTEN-4G") {
do4Gtest = true
}
if (env.GITHUB_PR_LABELS.contains('5G-NR')) {
} else if (LABEL_CHECK == 'SHORTEN-5G') {
do5Gtest = true
}
if (env.GITHUB_PR_LABELS.contains('nrUE')) {
} else if (LABEL_CHECK == 'SHORTEN-5G-UE') {
do5GUeTest = true
}
if (env.GITHUB_PR_LABELS.contains('documentation')) {
} else if (LABEL_CHECK == 'SHORTEN-4G-5G-UE') {
do4Gtest = true
do5GUeTest = true
} else if (LABEL_CHECK == 'documentation') {
doBuild = false
} else {
// is "BUILD-ONLY", will only build
}
} else {
// PUSH event
do4Gtest = true
do5Gtest = true
}
echo """
CI decision summary:
doBuild = ${doBuild}
do4Gtest = ${do4Gtest}
do5Gtest = ${do5Gtest}
do5GUeTest = ${do5GUeTest}
"""
}
}
}
stage ("Verify Guidelines") {
steps {
echo "Git URL is ${GIT_URL}"
echo "Job Name is ${JOB_NAME}"
echo "Build Id is ${BUILD_ID}"
echo "Git URL is ${GIT_URL}"
echo "GitLab Act is ${env.gitlabActionType}"
script {
if (env.GITHUB_PR_NUMBER) {
if ("MERGE".equals(env.gitlabActionType)) {
// since a bit, in push events, gitlabUserEmail is not populated
gitCommitAuthorEmailAddr = env.gitlabUserEmail
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
// Validate MR commits: checks for missing Signed-off-by and merge commits
def mrValidationLog = "signedCommit_${env.BUILD_NUMBER}.log"
def mrValidationExitCode = sh(
script: "bash ./ci-scripts/pre-ci-check.sh -s ${env.GITHUB_PR_HEAD_SHA} -t origin/${env.GITHUB_PR_TARGET_BRANCH} > ${mrValidationLog} 2>&1",
script: "bash ./ci-scripts/pre-ci-check.sh -s origin/${env.gitlabSourceBranch} -t origin/${env.gitlabTargetBranch} > ${mrValidationLog} 2>&1",
returnStatus: true
)
def mrValidationMessage = readFile(mrValidationLog).trim()
sh "rm -f ${mrValidationLog}"
if (mrValidationExitCode >= 1) {
mrValidationWarning = mrValidationMessage
addGitLabMRComment comment: "${mrValidationMessage}"
}
if (mrValidationExitCode >= 2) {
error("${mrValidationMessage}")
@@ -163,21 +104,26 @@ pipeline {
} else {
echo "Git Branch is ${GIT_BRANCH}"
echo "Git Commit is ${GIT_COMMIT}"
// since a bit, in push events, gitlabUserEmail is not populated
gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}'
gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim()
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
}
}
}
}
stage ("Internal-Repo-Push") {
stage ("Local-Repo-Push") {
steps {
script {
triggerDownstreamJob ('RAN-Internal-Repo-Push')
triggerDownstreamJob ('RAN-Local-Repo-Push', 'Local-Repo-Push')
}
}
post {
failure {
script {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Cannot perform CI - merge validation failed (merge conflict, git operation failure, or internal CI error)."
addGitLabMRComment comment: message
currentBuild.result = 'FAILURE'
failingStages += '\n * Internal-Repo-Push - merge validation failed (merge conflict, git operation failure, or internal CI error)'
}
}
}
@@ -189,7 +135,7 @@ pipeline {
stage ("Ubuntu-Image-Builder") {
steps {
script {
triggerDownstreamJob ('RAN-Ubuntu-Image-Builder')
triggerDownstreamJob ('RAN-Ubuntu18-Image-Builder', 'Ubuntu-Image-Builder')
}
}
post {
@@ -197,7 +143,7 @@ pipeline {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
ubuntuBuildStatus = finalizeDownstreamJob('RAN-Ubuntu-Image-Builder')
ubuntuBuildStatus = finalizeDownstreamJob('RAN-Ubuntu18-Image-Builder')
}
}
failure {
@@ -211,7 +157,7 @@ pipeline {
stage ("Ubuntu-ARM-Image-Builder") {
steps {
script {
triggerDownstreamJob ('RAN-Ubuntu-ARM-Image-Builder')
triggerDownstreamJob ('RAN-Ubuntu-ARM-Image-Builder', 'Ubuntu-ARM-Image-Builder')
}
}
post {
@@ -233,7 +179,7 @@ pipeline {
stage ("Ubuntu-Jetson-Image-Builder") {
steps {
script {
triggerDownstreamJob ('RAN-Ubuntu-Jetson-Image-Builder')
triggerDownstreamJob ('RAN-Ubuntu-Jetson-Image-Builder', 'Ubuntu-Jetson-Image-Builder')
}
}
post {
@@ -255,7 +201,7 @@ pipeline {
stage ("RHEL-Cluster-Image-Builder") {
steps {
script {
triggerDownstreamJob ('RAN-RHEL-Cluster-Image-Builder')
triggerDownstreamJob ('RAN-RHEL8-Cluster-Image-Builder', 'RHEL-Cluster-Image-Builder')
}
}
post {
@@ -263,7 +209,7 @@ pipeline {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
rhelBuildStatus = finalizeDownstreamJob('RAN-RHEL-Cluster-Image-Builder')
rhelBuildStatus = finalizeDownstreamJob('RAN-RHEL8-Cluster-Image-Builder')
}
}
failure {
@@ -277,7 +223,7 @@ pipeline {
stage ("ARM-Cross-Compile") {
steps {
script {
triggerDownstreamJob ('RAN-ARM-Cross-Compile-Builder')
triggerDownstreamJob ('RAN-ARM-Cross-Compile-Builder', 'ARM-Cross-Compilation')
}
}
post {
@@ -299,11 +245,11 @@ pipeline {
}
}
stage ("DockerHub-Push") {
when { expression {doBuild && !(env.GITHUB_PR_NUMBER)} }
when { expression {doBuild && "PUSH".equals(env.gitlabActionType)} }
steps {
script {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
triggerDownstreamJob ('RAN-DockerHub-Push')
triggerDownstreamJob ('RAN-DockerHub-Push', 'DockerHub-Push')
}
}
}
@@ -323,7 +269,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-PhySim-Cluster-5G')
triggerDownstreamJob ('RAN-PhySim-Cluster-5G', 'PhySim-Cluster-5G')
}
}
post {
@@ -346,7 +292,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-PhySim-GraceHopper-5G')
triggerDownstreamJob ('RAN-PhySim-GraceHopper-5G', 'PhySim-GraceHopper-5G')
}
}
post {
@@ -369,7 +315,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-Channel-Simulation')
triggerDownstreamJob ('RAN-Channel-Simulation', 'Channel-Simulation')
}
}
post {
@@ -392,7 +338,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-PhySim-Cluster-4G')
triggerDownstreamJob ('RAN-PhySim-Cluster-4G', 'PhySim-Cluster-4G')
}
}
post {
@@ -415,7 +361,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-RF-Sim-Test-4G')
triggerDownstreamJob ('RAN-RF-Sim-Test-4G', 'RF-Sim-Test-4G')
}
}
post {
@@ -438,7 +384,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-VRT-Sim-Test-5G')
triggerDownstreamJob ('RAN-VRT-Sim-Test-5G', 'VRT-Sim-Test-5G')
}
}
post {
@@ -461,7 +407,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-RF-Sim-Test-5G')
triggerDownstreamJob ('RAN-RF-Sim-Test-5G', 'RF-Sim-Test-5G')
}
}
post {
@@ -484,7 +430,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('OAI-FLEXRIC-RAN-Integration-Test')
triggerDownstreamJob ('OAI-FLEXRIC-RAN-Integration-Test', 'OAI-FLEXRIC-RAN-Integration-Test')
}
}
post {
@@ -507,7 +453,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-L2-Sim-Test-4G')
triggerDownstreamJob ('RAN-L2-Sim-Test-4G', 'L2-Sim-Test-4G')
}
}
post {
@@ -530,7 +476,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-LTE-FDD-LTEBOX-Container')
triggerDownstreamJob ('RAN-LTE-FDD-LTEBOX-Container', 'LTE-FDD-LTEBOX-Container')
}
}
post {
@@ -538,13 +484,13 @@ pipeline {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
lteFDDB200Status = finalizeDownstreamJob('RAN-LTE-FDD-LTEBOX-Container')
lteTDDB200Status = finalizeDownstreamJob('RAN-LTE-FDD-LTEBOX-Container')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
failingStages += lteFDDB200Status
failingStages += lteTDDB200Status
}
}
}
@@ -554,7 +500,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-LTE-FDD-OAIUE-OAICN4G-Container')
triggerDownstreamJob ('RAN-LTE-FDD-OAIUE-OAICN4G-Container', 'LTE-FDD-OAIUE-OAICN4G-Container')
}
}
post {
@@ -577,7 +523,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-LTE-TDD-LTEBOX-Container')
triggerDownstreamJob ('RAN-LTE-TDD-LTEBOX-Container', 'LTE-TDD-LTEBOX-Container')
}
}
post {
@@ -585,13 +531,13 @@ pipeline {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
lteTDDB200Status = finalizeDownstreamJob('RAN-LTE-TDD-LTEBOX-Container')
lteFDDB200Status = finalizeDownstreamJob('RAN-LTE-TDD-LTEBOX-Container')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
failingStages += lteTDDB200Status
failingStages += lteFDDB200Status
}
}
}
@@ -600,7 +546,7 @@ pipeline {
when { expression {do4Gtest || do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-NSA-B200-Module-LTEBOX-Container')
triggerDownstreamJob ('RAN-NSA-B200-Module-LTEBOX-Container', 'NSA-B200-Module-LTEBOX-Container')
}
}
post {
@@ -623,7 +569,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-B200-Module-SABOX-Container')
triggerDownstreamJob ('RAN-SA-B200-Module-SABOX-Container', 'SA-B200-Module-SABOX-Container')
}
}
post {
@@ -646,7 +592,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-gNB-N300-Timing-Phytest-LDPC')
triggerDownstreamJob ('RAN-gNB-N300-Timing-Phytest-LDPC', 'gNB-N300-Timing-Phytest-LDPC')
}
}
post {
@@ -669,7 +615,7 @@ pipeline {
when { expression {do4Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-LTE-TDD-2x2-Container')
triggerDownstreamJob ('RAN-LTE-TDD-2x2-Container', 'LTE-TDD-2x2-Container')
}
}
post {
@@ -692,7 +638,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-AW2S-CN5G')
triggerDownstreamJob ('RAN-SA-AW2S-CN5G', 'SA-AW2S-CN5G')
}
}
post {
@@ -711,11 +657,34 @@ pipeline {
}
}
}
stage ("Sanity-Check OAI-CN5G") {
when { expression {do5Gtest} }
steps {
script {
triggerCN5GDownstreamJob ('OAI-CN5G-COTS-UE-Test', 'OAI-CN5G-COTS-UE-Test')
}
}
post {
always {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
cn5gCOTSUESanityCheck = finalizeDownstreamJob('OAI-CN5G-COTS-UE-Test')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
failingStages += cn5gCOTSUESanityCheck
}
}
}
}
stage ("SA-AERIAL-CN5G") {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-AERIAL-CN5G')
triggerDownstreamJob ('RAN-SA-AERIAL-CN5G', 'SA-AERIAL-CN5G')
}
}
post {
@@ -738,7 +707,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-Multi-Antenna-CN5G')
triggerDownstreamJob ('RAN-SA-Multi-Antenna-CN5G', 'SA-Multi-Antenna-CN5G')
}
}
post {
@@ -761,7 +730,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-FHI72-CN5G')
triggerDownstreamJob ('RAN-SA-FHI72-CN5G', 'SA-FHI72-CN5G')
}
}
post {
@@ -784,7 +753,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-FHI72-MPLANE-CN5G')
triggerDownstreamJob ('RAN-SA-FHI72-MPLANE-CN5G', 'SA-FHI72-MPLANE-CN5G')
}
}
post {
@@ -807,7 +776,7 @@ pipeline {
when { expression {do5Gtest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-Handover-CN5G')
triggerDownstreamJob ('RAN-SA-Handover-CN5G', 'SA-Handover-CN5G')
}
}
post {
@@ -830,7 +799,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-AERIAL-OAIUE-CN5G')
triggerDownstreamJob ('RAN-SA-AERIAL-OAIUE-CN5G', 'SA-AERIAL-OAIUE-CN5G')
}
}
post {
@@ -853,7 +822,7 @@ pipeline {
when { expression {do5Gtest || do5GUeTest} }
steps {
script {
triggerDownstreamJob ('RAN-SA-OAIUE-CN5G')
triggerDownstreamJob ('RAN-SA-OAIUE-CN5G', 'SA-OAIUE-CN5G')
}
}
post {
@@ -878,47 +847,21 @@ pipeline {
post {
success {
script {
if (env.GITHUB_PR_NUMBER) {
if (mrValidationWarning) {
def message = "**CI Build:** [#${env.BUILD_NUMBER}](${BUILD_URL}) | **Passed**"
message += "\n\n**Validation:** " + mrValidationWarning
githubPRComment comment: githubPRMessage(message)
}
githubNotify account: params.gitAccount,
repo: params.gitRepo,
credentialsId: 'github-jenkins-duranta',
sha: env.GITHUB_PR_HEAD_SHA,
status: 'SUCCESS',
description: 'Build success',
targetUrl: BUILD_URL,
context: 'Jenkins Duranta CI'
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
if ("MERGE".equals(env.gitlabActionType)) {
addGitLabMRComment comment: message
def message2 = message + " -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
}
echo "Pipeline is SUCCESSFUL"
}
}
failure {
script {
if (env.GITHUB_PR_NUMBER) {
def message = "**CI Build:** [#${env.BUILD_NUMBER}](${BUILD_URL}) | **Failed** on the following stages:"
if (failingStages) {
message += failingStages
} else {
message += "\nThe pipeline may have failed due to CI, validation, or scripting error. See the build for more details."
}
if (mrValidationWarning) {
message += '\n\n**Validation:** ' + mrValidationWarning
}
if (env.GITHUB_PR_LABELS) {
githubPRComment comment: githubPRMessage(message)
}
githubNotify account: params.gitAccount,
repo: params.gitRepo,
credentialsId: 'github-jenkins-duranta',
sha: env.GITHUB_PR_HEAD_SHA,
status: 'FAILURE',
description: 'Build failed',
targetUrl: BUILD_URL,
context: 'Jenkins Duranta CI'
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
if ("MERGE".equals(env.gitlabActionType)) {
def fullMessage = message + '\n\nList of failing test stages:' + failingStages
addGitLabMRComment comment: fullMessage
def message2 = message + " -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
}
echo "Pipeline FAILED"
}
@@ -928,35 +871,41 @@ pipeline {
// ---- Slave Job functions
def triggerDownstreamJob (jobName) {
// Workaround for the "cancelled" pipeline notification
def triggerDownstreamJob (jobName, gitlabStatusName) {
def MR_NUMBER = "MERGE".equals(env.gitlabActionType) ? env.gitlabMergeRequestIid : 'develop'
// Workaround for the "cancelled" GitLab pipeline notification
// The downstream job is triggered with the propagate false so the following commands are executed
// Its status is now PASS/SUCCESS from a stage pipeline point of view
// localStatus variable MUST be analyzed to properly assess the status
def localStatus = build job: jobName,
parameters: [
string(name: 'targetRepo', value: String.valueOf(env.GIT_URL)),
string(name: 'sourceRepo', value: String.valueOf(env.GITHUB_PR_URL ?: env.GIT_URL)),
string(name: 'sourceBranch', value: String.valueOf(env.GITHUB_PR_SOURCE_BRANCH ?: gitLocalBranch)),
string(name: 'sourceCommit', value: String.valueOf(env.GITHUB_PR_HEAD_SHA ?: env.GIT_COMMIT)),
string(name: 'requestNumber', value: String.valueOf(env.GITHUB_PR_NUMBER ?: gitLocalBranch)),
booleanParam(name: 'mergeWithTarget', value: env.GITHUB_PR_NUMBER != null),
string(name: 'targetBranch', value: (env.GITHUB_PR_TARGET_BRANCH ?: gitLocalBranch)),
string(name: 'targetRepo', value: String.valueOf(env.gitlabTargetRepoHttpUrl)),
string(name: 'sourceRepo', value: String.valueOf(env.gitlabSourceRepoHttpUrl)),
string(name: 'sourceBranch', value: String.valueOf(env.gitlabSourceBranch)),
string(name: 'sourceCommit', value: String.valueOf(env.gitlabMergeRequestLastCommit)),
string(name: 'requestNumber', value: String.valueOf(MR_NUMBER)),
booleanParam(name: 'mergeWithTarget', value: "MERGE".equals(env.gitlabActionType)),
string(name: 'targetBranch', value: String.valueOf(env.gitlabTargetBranch)),
string(name: 'repository', value: String.valueOf(params.ciRepositoryURL)),
string(name: 'branch', value: String.valueOf(branch))
string(name: 'branch', value: "${env.gitlabSourceBranch.replace('/', '-')}-${env.gitlabMergeRequestLastCommit}")
], propagate: false
def localResult = localStatus.getResult()
echo "${jobName} Slave Job status is ${localResult}"
downstreamResults[jobName] = localStatus.resultIsBetterOrEqualTo('SUCCESS') ? 'SUCCESS' : 'FAILURE'
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
echo "${jobName} Slave Job is OK"
} else {
error "${jobName} Slave Job is KO"
gitlabCommitStatus(name: gitlabStatusName) {
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
echo "${jobName} Slave Job is OK"
} else {
error "${jobName} Slave Job is KO"
}
}
}
def triggerCN5GDownstreamJob (jobName) {
def fullRanTag = params.internalRegistry + '/oai-gnb:' + "${branch}"
def triggerCN5GDownstreamJob (jobName, gitlabStatusName) {
if ("MERGE".equals(env.gitlabActionType)) {
fullRanTag = OAI_Registry + '/oai-gnb:' + "${env.gitlabSourceBranch.replace('/', '-')}-${env.gitlabMergeRequestLastCommit}"
} else {
fullRanTag = OAI_Registry + '/oai-gnb:develop-' + env.GIT_COMMIT
}
// Workaround for the "cancelled" GitLab pipeline notification
// The downstream job is triggered with the propagate false so the following commands are executed
// Its status is now PASS/SUCCESS from a stage pipeline point of view
@@ -967,11 +916,12 @@ def triggerCN5GDownstreamJob (jobName) {
], propagate: false
def localResult = localStatus.getResult()
echo "${jobName} Slave Job status is ${localResult}"
downstreamResults[jobName] = localStatus.resultIsBetterOrEqualTo('SUCCESS') ? 'SUCCESS' : 'FAILURE'
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
echo "${jobName} Slave Job is OK"
} else {
error "${jobName} Slave Job is KO"
gitlabCommitStatus(name: gitlabStatusName) {
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
echo "${jobName} Slave Job is OK"
} else {
error "${jobName} Slave Job is KO"
}
}
}
@@ -979,13 +929,12 @@ def finalizeDownstreamJob(jobName) {
lock ('Parent-Lock') {
// In case of any non-success, we are retrieving the HTML report of the last completed
// downstream job. The only drop-back is that we may retrieve the HTML report of a previous build
def fileName
if (jobName == 'OAI-CN5G-COTS-UE-Test') {
fileName = "test_results_oai_cn5g_cots_ue.html"
} else {
fileName = "test_results-${jobName}.html"
}
def artifactUrl = BUILD_URL
artifactUrl = BUILD_URL
if (!fileExists(fileName)) {
copyArtifacts(projectName: jobName,
filter: 'test_results*.html',
@@ -1001,15 +950,6 @@ def finalizeDownstreamJob(jobName) {
// no need to add a prefixed '/'
artifactUrl += 'artifact/' + fileName
}
if (env.GITHUB_PR_NUMBER) {
githubNotify account: params.gitAccount,
repo: params.gitRepo,
credentialsId: "github-jenkins-duranta",
sha: env.GITHUB_PR_HEAD_SHA,
status: downstreamResults.getOrDefault(jobName, 'FAILURE'),
targetUrl: "${artifactUrl}",
context: jobName
}
artifactUrl = "\n * [${jobName}](${artifactUrl})"
return artifactUrl
}

View File

@@ -23,54 +23,11 @@ pipeline {
lock(extra: lockResources)
}
stages {
stage("Job init") {
steps {
buildName "${params.requestNumber ?: params.targetBranch}"
buildDescription "Branch: ${params.sourceBranch}"
}
}
stage('Checkout') {
steps {
script {
if (params.mergeWithTarget) {
echo "PR triggered - checking out merge ref for PR #${params.requestNumber}"
try {
checkout([
$class: 'GitSCM',
branches: [[name: "refs/remotes/origin/pr/${params.requestNumber}/merge"]],
userRemoteConfigs: [[
url: params.targetRepo,
refspec: "+refs/pull/${params.requestNumber}/merge:refs/remotes/origin/pr/${params.requestNumber}/merge",
credentialsId: 'github-jenkins-duranta'
]]
])
} catch (e) {
error("Checkout failed for PR #${params.requestNumber} - " +
"merge ref not found. The PR likely has a conflict with ${params.targetBranch} " +
"that must be resolved before CI can run. (${e.message})")
}
} else {
echo "Push triggered - checking out branch ${params.targetBranch}"
try {
checkout([
$class: 'GitSCM',
branches: [[name: params.targetBranch]],
userRemoteConfigs: [[
url: params.targetRepo,
credentialsId: 'github-jenkins-duranta'
]]
])
} catch (e) {
error("Checkout failed for branch ${params.targetBranch} from ${params.targetRepo}. (${e.message})")
}
}
}
}
}
stage('Verify parameters') {
steps {
script {
def missingParams = []
if (!params.sourceRepo?.trim()) { missingParams << 'sourceRepo' }
if (!params.sourceBranch?.trim()) { missingParams << 'sourceBranch' }
if (!params.sourceCommit?.trim()) { missingParams << 'sourceCommit' }
if (params.mergeWithTarget) {
@@ -82,6 +39,7 @@ pipeline {
error "Missing required parameters: ${missingParams.join(', ')}"
}
echo "Source Repo : ${params.sourceRepo}"
echo "Source Branch : ${params.sourceBranch}"
echo "Source Commit : ${params.sourceCommit}"
echo "Merge : ${params.mergeWithTarget}"
@@ -95,17 +53,49 @@ pipeline {
stage('Prepare workspace') {
steps {
sh """
git config user.email "oaicicdteam@openairinterface.org"
git config user.name "Duranta Jenkins"
git config user.email "jenkins@openairinterface.org"
git config user.name "OAI Jenkins"
git remote remove source || true
git remote remove target || true
git remote remove internal-repo || true
"""
}
}
stage('Add source repo & fetch branches') {
steps {
sh """
git remote add source ${params.sourceRepo} || true
git fetch source ${params.sourceBranch}
"""
script {
if (params.mergeWithTarget) {
sh """
git remote add target ${params.targetRepo} || true
git fetch target ${params.targetBranch}
"""
}
}
}
}
stage('Create testing branch for CI') {
steps {
sh """
# Checkout source commit
git checkout -B ${params.branch}
git checkout -B ${params.branch} ${params.sourceCommit}
"""
}
}
stage('Merge target into source') {
when { expression { return params.mergeWithTarget } }
steps {
sh """
echo "Merging target branch ${params.targetBranch} into source branch ${params.branch}"
if ! git merge --ff target/${params.targetBranch} \
-m "Merge ${params.targetBranch} into ${params.sourceBranch} for CI"; then
echo "Merge conflicts detected. Aborting."
git merge --abort || true
exit 1
fi
"""
}
}

View File

@@ -46,9 +46,9 @@ pipeline {
stage ("Push to DockerHub") {
steps {
script {
def WEEK_REF = sh returnStdout: true, script: 'date +"%Y.w%V"'
WEEK_REF = sh returnStdout: true, script: 'date +"%Y.w%V"'
WEEK_REF = WEEK_REF.trim()
def WEEK_TAG = sh returnStdout: true, script: 'python3 ./ci-scripts/provideUniqueImageTag.py --start_tag ' + WEEK_REF
WEEK_TAG = sh returnStdout: true, script: 'python3 ./ci-scripts/provideUniqueImageTag.py --start_tag ' + WEEK_REF
WEEK_TAG = WEEK_TAG.trim()
if ((params.forceTag != null) && (params.tagToUse != null)) {
if (params.forceTag) {
@@ -56,7 +56,7 @@ pipeline {
echo "Forced Tag is ${WEEK_TAG}"
}
}
def WEEK_SHA = sh returnStdout: true, script: 'git log -n1 --pretty=format:"%H" origin/develop'
WEEK_SHA = sh returnStdout: true, script: 'git log -n1 --pretty=format:"%H" origin/develop'
WEEK_SHA = WEEK_SHA.trim()
withCredentials([

View File

@@ -92,7 +92,7 @@ pipeline {
sourceBranch = selected_ref.replaceFirst("^origin/", "")
commitID = sh(script: "git rev-parse ${selected_ref}", returnStdout: true).trim()
echo "Found branch ${sourceBranch}, commit ${commitID}"
testBranch = "${sourceBranch}-${commitID}"
testBranch = "${sourceBranch}"
}
echo "CI executor node : ${pythonExecutor}"

View File

@@ -7,7 +7,7 @@
#define N_ANTENNA_UL 1
#define TDD 1
log_options: "all.level=info,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
log_options: "all.level=debug,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
log_filename: "/tmp/ue.log",
/* Enable remote API and Web interface */

View File

@@ -7,7 +7,7 @@
#define N_ANTENNA_UL 1
#define TDD 1
log_options: "all.level=info,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
log_options: "all.level=debug,all.max_size=0,nas.level=debug,nas.max_size=1,rrc.level=debug,rrc.max_size=1",
log_filename: "/tmp/ue.log",
/* Enable remote API and Web interface */

View File

@@ -0,0 +1,115 @@
#!/bin/bash
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
function usage {
echo "OAI GitLab merge request applying script"
echo ""
echo "Usage:"
echo "------"
echo ""
echo " checkGitLabMergeRequestLabels.sh [OPTIONS]"
echo ""
echo "Options:"
echo "------------------"
echo ""
echo " --mr-id ####"
echo " Specify the ID of the merge request."
echo ""
echo " --help OR -h"
echo " Print this help message."
echo ""
}
if [ $# -ne 2 ] && [ $# -ne 1 ]
then
echo "Syntax Error: not the correct number of arguments"
echo ""
usage
exit 1
fi
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-h|--help)
shift
usage
exit 0
;;
--mr-id)
MERGE_REQUEST_ID="$2"
shift
shift
;;
*)
echo "Syntax Error: unknown option: $key"
echo ""
usage
exit 1
esac
done
LABELS=`curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/$MERGE_REQUEST_ID" | jq '.labels' || true`
IS_MR_DOCUMENTATION=`echo $LABELS | grep -ic documentation`
IS_MR_BUILD_ONLY=`echo $LABELS | grep -c BUILD-ONLY`
IS_MR_CI=`echo $LABELS | grep -c CI`
IS_MR_4G=`echo $LABELS | grep -c 4G-LTE`
IS_MR_5G=`echo $LABELS | grep -c 5G-NR`
IS_MR_5G_UE=`echo $LABELS | grep -c nrUE`
# none is present! No CI
if [ $IS_MR_BUILD_ONLY -eq 0 ] && [ $IS_MR_CI -eq 0 ] && [ $IS_MR_4G -eq 0 ] && [ $IS_MR_5G -eq 0 ] && [ $IS_MR_DOCUMENTATION -eq 0 ] && [ $IS_MR_5G_UE -eq 0 ]
then
echo "NONE"
exit 0
fi
# 4G and 5G or CI labels: run everything (4G, 5G)
if [ $IS_MR_4G -eq 1 ] && [ $IS_MR_5G -eq 1 ] || [ $IS_MR_CI -eq 1 ]
then
echo "FULL"
exit 0
fi
if [ $IS_MR_5G_UE -eq 1 ] && [ $IS_MR_4G -eq 1 ]
then
echo "SHORTEN-4G-5G-UE"
exit 0
fi
# 4G is present: run only 4G
if [ $IS_MR_4G -eq 1 ]
then
echo "SHORTEN-4G"
exit 0
fi
# 5G is present: run only 5G
if [ $IS_MR_5G -eq 1 ]
then
echo "SHORTEN-5G"
exit 0
fi
if [ $IS_MR_5G_UE -eq 1 ]
then
echo "SHORTEN-5G-UE"
exit 0
fi
# BUILD-ONLY is present: only build stages
if [ $IS_MR_BUILD_ONLY -eq 1 ]
then
echo "BUILD-ONLY"
exit 0
fi
# Documentation is present: don't do anything
if [ $IS_MR_DOCUMENTATION -eq 1 ]
then
echo "documentation"
exit 0
fi

View File

@@ -217,19 +217,11 @@ amarisoft_00105_40MHz:
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_fhi72_mplane_40MHz/multi-00105-40.cfg &
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
NetworkScript: ip netns exec ue1 ip a show dev pdn0
Tracing:
Start: '' # nothing to be done
Stop: '' # nothing to be done
Collect: 'cp /tmp/ue.log %%log_dir%%'
amarisoft_00105_100MHz:
Host: amariue
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_fhi72_mplane_100MHz/multi-00105-100.cfg &
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
NetworkScript: ip netns exec ue1 ip a show dev pdn0
Tracing:
Start: '' # nothing to be done
Stop: '' # nothing to be done
Collect: 'cp /tmp/ue.log %%log_dir%%'
amarisoft_ue_1:
Host: amariue
AttachScript: /root/lteue-linux-2025-03-15/ws.js 127.0.0.1:9002 '{"message":"power_on","ue_id":1}'

View File

@@ -95,13 +95,13 @@ class Analysis():
test_summary['Nbfail'] = nb_failed
return nb_failed == 0, test_summary, test_result
def analyze_rt_stats(thresholds, stat_files):
def analyze_rt_stats(thresholds, L1_stats, MAC_stats):
with open(thresholds, 'r') as f:
datalog_rt_stats = yaml.load(f, Loader=yaml.FullLoader)
rt_keys = datalog_rt_stats['Ref']
real_time_stats = {}
for sf in stat_files:
for sf in [L1_stats, MAC_stats]:
with open(sf, 'r') as f:
for line in f.readlines():
for k in rt_keys:

View File

@@ -401,7 +401,7 @@ class Containerize():
# I would like to run it with --rm and mount the ctest result directory to avoid 'docker cp'
# below, but then permissions are messed up and we can't remove the directory without sudo
# making the next pipeline fail
ret = cmd.run(f'docker run -a STDOUT {runtime_opt} --shm-size=2g --workdir /oai-ran/build/ --env LD_LIBRARY_PATH=/oai-ran/build/ --name ran-unittests ran-unittests:{baseTag} ctest --no-label-summary -j$(nproc) {ctest_opt}')
ret = cmd.run(f'docker run -a STDOUT {runtime_opt} --workdir /oai-ran/build/ --env LD_LIBRARY_PATH=/oai-ran/build/ --name ran-unittests ran-unittests:{baseTag} ctest --no-label-summary -j$(nproc) {ctest_opt}')
cmd.run('docker cp ran-unittests:/oai-ran/build/Testing/Temporary/LastTest.log .')
archiveArtifact(cmd, ctx, f'{lSourcePath}/LastTest.log')
cmd.run('docker cp ran-unittests:/oai-ran/build/Testing/Temporary/LastTestsFailed.log .')
@@ -644,7 +644,7 @@ class Containerize():
logging.error('\u001B[1m Undeploying objects Failed\u001B[0m')
return success
def AnalyzeRTStatsObject(self, HTML, node, ctx, thresholds, service=None, stats_files=None):
def AnalyzeRTStatsObject(self, HTML, node, ctx, thresholds, service=None):
logging.info(f'Analyzing realtime stats from server: {node}')
yaml = self.yamlPath.strip('/')
wd = f'{self.workspace}/{yaml}'
@@ -660,20 +660,12 @@ class Containerize():
raise RuntimeError(f"Requested service {s} not found among services: {deployed_services}")
logging.info(f"Analyzing deployed service '{s}'")
# similar to BuildRunTests(), use docker cp to avoid problems with permissions
local_files = []
for sf in stats_files:
basename = os.path.basename(sf)
ret = cmd.run(f'docker compose -f {wd_yaml} cp {s}:{sf} {wd}/')
if ret.returncode != 0:
logging.error(f"Cannot retrieve {s}:{sf}")
return False
file = archiveArtifact(cmd, ctx, f"{wd}/{basename}")
if not file:
logging.error(f"Cannot retrieve file {basename}")
return False
local_files.append(file)
cmd.run(f'docker compose -f {wd_yaml} cp {s}:/opt/oai-gnb/nrL1_stats.log {wd}/')
l1_file = archiveArtifact(cmd, ctx, f"{wd}/nrL1_stats.log")
cmd.run(f'docker compose -f {wd_yaml} cp {s}:/opt/oai-gnb/nrMAC_stats.log {wd}/')
mac_file = archiveArtifact(cmd, ctx, f"{wd}/nrMAC_stats.log")
logging.info(f"check against thresholds from {thresholds}")
success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, local_files)
success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, l1_file, mac_file)
HTML.CreateHtmlDataLogTable(datalog_rt_stats)
return success

View File

@@ -75,12 +75,12 @@ class HTMLManagement():
self.htmlFile.write(' <tr style="border-collapse: collapse; border: none;">\n')
self.htmlFile.write(' <td style="border-collapse: collapse; border: none;">\n')
self.htmlFile.write(' <a href="http://www.openairinterface.org/">\n')
self.htmlFile.write(' <img src="https://raw.githubusercontent.com/duranta-project/governance/main/logos/Duranta-Logo-Color.png" alt="" border="none" style="margin-right: 2rem;" width=150>\n')
self.htmlFile.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n')
self.htmlFile.write(' </img>\n')
self.htmlFile.write(' </a>\n')
self.htmlFile.write(' </td>\n')
self.htmlFile.write(' <td style="border-collapse: collapse; border: none; vertical-align: center;">\n')
self.htmlFile.write(' <b><font size = "6">TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n')
self.htmlFile.write(' <b><font size = "6">Job Summary -- Job: TEMPLATE_JOB_NAME -- Build-ID: TEMPLATE_BUILD_ID</font></b>\n')
self.htmlFile.write(' </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' </table>\n')

View File

@@ -184,8 +184,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
}
);
RUs = (

View File

@@ -184,8 +184,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
}
);
RUs = (

View File

@@ -216,7 +216,6 @@ L1s =
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
);

View File

@@ -216,7 +216,6 @@ L1s =
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
);

View File

@@ -216,7 +216,6 @@ L1s =
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
);

View File

@@ -216,7 +216,6 @@ L1s =
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 200;
}
);

View File

@@ -1,222 +0,0 @@
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 208; mnc = 99; mnc_length = 2;});
tr_s_preference = "local_mac"
////////// Physical parameters:
min_rxtxtime = 6;
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
# this is 4412.64 MHz
absoluteFrequencySSB = 694176;
dl_frequencyBand = 79;
# this is 4400.94 MHz
dl_absoluteFrequencyPointA = 693396;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=41,L=24 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 6368;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 79;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 6368;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 13;
preambleReceivedTargetPower = -118;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
#one (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -90;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ({ ipv4 = "192.168.12.26"; port = 36412; });
NETWORK_INTERFACES :
{
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
});
L1s = (
{
tr_n_preference = "local_mac";
});
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 50;
eNB_instances = [0];
});
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
};

View File

@@ -1,32 +0,0 @@
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : gNB Processing Time (us) from datalog_rt_stats.default.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
L1 Tx processing : 190.0
DLSCH encoding : 120.0
L1 Rx processing : 235.0
UL segments decoding : 120.0
PUSCH inner-receiver : 150.0
UL Indication : 2.0
Slot Indication : 10.0
feprx : 40.0
feptx_ofdm (per port, half_slot) : 30
feptx_total : 52
DeviationThreshold :
L1 Tx processing : 0.25
DLSCH encoding : 0.25
L1 Rx processing : 0.25
UL segments decoding : 0.25
PUSCH inner-receiver : 0.25
UL Indication : 1.00
Slot Indication : 0.50
feprx : 0.25
feptx_ofdm (per port, half_slot) : 0.25
feptx_total : 0.25

View File

@@ -1,40 +0,0 @@
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
#this is a configuration file
#used to build real time processing statistics
#for 5G NR phy test (gNB terminate)
Title : UE Processing Time (us) from datalog_rt_stats.ue.40.vrtsim.yaml
ColNames :
- Metric
- Average; Max; Count
- Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)
Ref :
RX_PDSCH_STATS : 62.0
DLSCH_RX_PDCCH_STATS : 30.5
RX_DFT_STATS : 5.5
DLSCH_CHANNEL_ESTIMATION_STATS : 39.0
DLSCH_DECODING_STATS : 178.0
DLSCH_LDPC_DECODING_STATS : 78.0
DLSCH_LLR_STATS : 25.0
DLSCH_LAYER_DEMAPPING : 8.5
DLSCH_PROCEDURES_STATS : 188.0
PHY_PROC_TX : 158.0
PUSCH_PROC_STATS : 167.0
ULSCH_LDPC_ENCODING_STATS : 43.0
ULSCH_ENCODING_STATS : 121.0
OFDM_MOD_STATS : 44.5
DeviationThreshold :
RX_PDSCH_STATS : 0.25
DLSCH_RX_PDCCH_STATS : 0.25
RX_DFT_STATS : 0.25
DLSCH_CHANNEL_ESTIMATION_STATS : 0.25
DLSCH_DECODING_STATS : 0.25
DLSCH_LDPC_DECODING_STATS : 0.25
DLSCH_LLR_STATS : 0.25
DLSCH_LAYER_DEMAPPING : 0.5
DLSCH_PROCEDURES_STATS : 0.25
PHY_PROC_TX : 0.25
PUSCH_PROC_STATS : 0.25
ULSCH_LDPC_ENCODING_STATS : 0.25
ULSCH_ENCODING_STATS : 0.25
OFDM_MOD_STATS : 0.25

View File

@@ -10,7 +10,8 @@
FROM ran-base:develop AS ran-tests
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libgtest-dev \
libyaml-cpp-dev \
libzmq3-dev \
@@ -25,9 +26,7 @@ WORKDIR /oai-ran
COPY . .
WORKDIR /oai-ran/build
RUN --mount=type=cache,target=/root/.cache/ccache/ \
--mount=type=cache,target=/root/.cache/cpm/ \
cmake .. -GNinja \
RUN cmake .. -GNinja \
-DENABLE_TESTS=ON -DOAI_ZMQ=ON -DCMAKE_BUILD_TYPE=Debug \
-DSANITIZE_ADDRESS=True -DOAI_VRTSIM_TAPS_CLIENT=ON -DOAI_RU_FRONTHAUL=ON \
&& \

View File

@@ -245,8 +245,7 @@ def ExecuteActionWithParam(action, ctx, node):
elif action == 'AnalyzeRTStats_Object':
yaml = test.findtext('stats_cfg')
service = test.findtext('service')
stats_files = (test.findtext('stats_file') or '').split()
success = CONTAINERS.AnalyzeRTStatsObject(HTML, node, ctx, yaml, service, stats_files)
success = CONTAINERS.AnalyzeRTStatsObject(HTML, node, ctx, yaml, service)
else:
logging.warning(f"unknown action {action}, skip step")

View File

@@ -25,6 +25,8 @@ function usage {
SOURCE_BRANCH=$(git rev-parse --abbrev-ref HEAD)
TARGET_BRANCH="origin/develop"
git fetch --quiet
while getopts ":s:t:h" opt; do
case "$opt" in
s)
@@ -55,20 +57,11 @@ done
# ----------------------------
# Merged commits
# ----------------------------
if [[ "$SOURCE_BRANCH" =~ ^[0-9a-f]{40}$ ]]; then
# note: if no branch could be found, it will result in "" and git rev-list
# will use the commit ID. Exclude "HEAD detached at", then use first branch
# name.
BRANCH_NAME=$(git branch -a --points-at $SOURCE_BRANCH --format='%(refname:short)' | grep -v detached | head -n1)
echo "SHA recognized in $SOURCE_BRANCH, using \"$BRANCH_NAME\" as branch name"
else
BRANCH_NAME="$SOURCE_BRANCH"
fi
if [[ ! "$BRANCH_NAME" =~ ^(origin/)?integration_[0-9]{4}_w[0-9]{2}$ ]]; then
mergeCommits=$(git rev-list --merges --abbrev-commit "$TARGET_BRANCH".."$SOURCE_BRANCH")
mergeCommits=$(git rev-list --merges --abbrev-commit "$TARGET_BRANCH".."$SOURCE_BRANCH")
if [[ ! "$SOURCE_BRANCH" =~ ^(origin/)?integration_[0-9]{4}_w[0-9]{2}$ ]]; then
if [[ -n "$mergeCommits" ]]; then
message="Error: Following merge commits are found in the source branch history. Please rebase your branch.\n\n"
message+="$(echo "$mergeCommits" | paste -sd ',' | sed 's/,/, /g')\n"
message="> ERROR: Following merge commits are found in the source branch history. Please rebase your branch.\n>\n"
message+="> $(echo "$mergeCommits" | paste -sd ',' -)\n"
echo -e "$message"
exit 3
fi
@@ -82,7 +75,7 @@ unsignedCommits=$(
if ! git log -1 --format=%B "$c" | grep -q "Signed-off-by:"; then
git log -1 --format='%h' "$c"
fi
done | paste -sd ',' | sed 's/,/, /g'
done | paste -sd ","
)
# ----------------------------
@@ -91,13 +84,13 @@ unsignedCommits=$(
message=""
if [ -n "$unsignedCommits" ]; then
message="The following commit(s) are missing a Signed-off-by:\n\n$unsignedCommits\n\n"
message+="Please use 'git commit -s' to sign your commits.\n"
message+="For detailed instructions, refer to the CONTRIBUTING file at the root of this repository."
message="> WARNING: The following commit(s) are missing a Signed-off-by:\n>\n> $unsignedCommits\n>\n"
message+="> Please use 'git commit -s' to sign your commits.\n>\n"
message+="> For detailed instructions, refer to the CONTRIBUTING file at the root of this repository."
echo -e "$message"
exit 1
else
message="All commits are signed off using 'git commit -s'."
message="> All commits are signed off using 'git commit -s'."
echo -e "$message"
exit 0
fi

View File

@@ -145,6 +145,6 @@ class RANManagement():
mac_file = archiveArtifact(cmd, ctx, f"{logdir}/nrMAC_stats.log")
logging.info(f"check against thresholds from {thresholds}")
success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, [l1_file, mac_file])
success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, l1_file, mac_file)
HTML.CreateHtmlDataLogTable(datalog_rt_stats)
return success

View File

@@ -26,7 +26,7 @@ class TestAnalysis(unittest.TestCase):
rtsf = "datalog_rt_stats.100.2x2.yaml"
l1f = "tests/analysis/gnb_phytest.success.nrL1.log"
macf = "tests/analysis/gnb_phytest.success.nrMAC.log"
status, s = cls_analysis.Analysis.analyze_rt_stats(rtsf, [l1f, macf])
status, s = cls_analysis.Analysis.analyze_rt_stats(rtsf, l1f, macf)
self.assertTrue(status)
self.assertEqual(s['Title'], "Processing Time (us) from datalog_rt_stats.100.2x2.yaml")
self.assertEqual(s['ColNames'], ["Metric", "Average; Max; Count", "Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)"])

View File

@@ -136,7 +136,7 @@ class TestDeploymentMethods(unittest.TestCase):
def test_create_workspace(self):
self.cont.workspace = tempfile.mkdtemp()
self.cont.repository = "https://github.com/duranta-project/openairinterface5g.git"
self.cont.repository = "https://gitlab.eurecom.fr/oai/openairinterface5g.git"
self.cont.branch = "develop"
ws = self.cont.Create_Workspace(self.node, self.html)
with cls_cmd.LocalCmd() as cmd:

View File

@@ -8,13 +8,13 @@ rm -f ${file}
cd ../../
python3 main.py \
--mode=InitiateHtml \
--repository=https://github.com/duranta-project/openairinterface5g.git \
--repository=https://gitlab.eurecom.fr/oai/openairinterface5g.git \
--branch=${branch} \
--XMLTestFile=tests/test-runner/test.xml
python3 main.py \
--mode=TesteNB \
--repository=https://github.com/duranta-project/openairinterface5g.git \
--repository=https://gitlab.eurecom.fr/oai/openairinterface5g.git \
--branch=${branch} \
--ranAllowMerge=true \
--targetBranch=develop \

View File

@@ -36,7 +36,6 @@
<desc>Analyze Real-Time Stats</desc>
<stats_cfg>datalog_rt_stats.100.4x4.fhi72.yaml</stats_cfg>
<service>oai-gnb</service>
<stats_file>/opt/oai-gnb/nrL1_stats.log /opt/oai-gnb/nrMAC_stats.log</stats_file>
<node>bulbul</node>
</testCase>

View File

@@ -44,7 +44,6 @@
<desc>Analyze Real-Time Stats</desc>
<stats_cfg>datalog_rt_stats.100.2x2.fhi72.cacofonix.yaml</stats_cfg>
<service>oai-gnb</service>
<stats_file>/opt/oai-gnb/nrL1_stats.log /opt/oai-gnb/nrMAC_stats.log</stats_file>
<node>cacofonix</node>
</testCase>

View File

@@ -1,82 +0,0 @@
<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->
<testCaseList>
<htmlTabRef>PHY-Test-40-vrtsim</htmlTabRef>
<htmlTabName>Timing phytest 40 MHz with vrtsim</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<testCase>
<class>Pull_Cluster_Image</class>
<desc>Pull Images from Cluster</desc>
<images>oai-gnb oai-nr-ue</images>
<node>caracal</node>
</testCase>
<testCase>
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>caracal</node>
</testCase>
<testCase>
<class>Deploy_Object</class>
<desc>Initialize gNB</desc>
<node>caracal</node>
<yaml_path>ci-scripts/yaml_files/phytest_vrtsim_40MHz</yaml_path>
<services>oai-gnb</services>
</testCase>
<testCase>
<class>Deploy_Object</class>
<desc>Initialize UE</desc>
<node>caracal</node>
<yaml_path>ci-scripts/yaml_files/phytest_vrtsim_40MHz</yaml_path>
<services>oai-nr-ue</services>
</testCase>
<testCase>
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
</testCase>
<testCase>
<class>AnalyzeRTStats_Object</class>
<desc>Analyze Real-Time Stats on gNB</desc>
<always_exec>true</always_exec>
<stats_cfg>datalog_rt_stats.gnb.40.vrtsim.yaml</stats_cfg>
<service>oai-gnb</service>
<stats_file>/opt/oai-gnb/nrL1_stats.log /opt/oai-gnb/nrMAC_stats.log</stats_file>
<node>caracal</node>
</testCase>
<testCase>
<class>AnalyzeRTStats_Object</class>
<desc>Analyze Real-Time Stats on UE</desc>
<always_exec>true</always_exec>
<stats_cfg>datalog_rt_stats.ue.40.vrtsim.yaml</stats_cfg>
<service>oai-nr-ue</service>
<stats_file>/opt/oai-nr-ue/nrL1_UE_stats-0.log</stats_file>
<node>caracal</node>
</testCase>
<testCase>
<class>Undeploy_Object</class>
<node>caracal</node>
<always_exec>true</always_exec>
<desc>Terminate gNB</desc>
<yaml_path>ci-scripts/yaml_files/phytest_vrtsim_40MHz</yaml_path>
<analysis>
<services>oai-gnb=EndsWithBye oai-nr-ue=EndsWithBye</services>
</analysis>
</testCase>
<testCase>
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<node>caracal</node>
<images>oai-nr-ue oai-gnb</images>
</testCase>
</testCaseList>

View File

@@ -1,6 +1,20 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
OAI Full Stack 4G-LTE RF simulation with containers
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI Full Stack 4G-LTE RF simulation with containers</font></b>
</td>
</tr>
</table>
This page is only valid for an `Ubuntu 22` host.
**Table of Contents**

View File

@@ -1,6 +1,22 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
OAI Full Stack 5G-NR RF simulation with containers
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI Full Stack 5G-NR RF simulation with containers</font></b>
</td>
</tr>
</table>
This page is only valid for an `Ubuntu 22` host.
**NOTE: this version (2023-01-27) has been updated for the `v1.5.0` version of the `OAI 5G CN`.**
**Table of Contents**

View File

@@ -20,8 +20,6 @@ ru_sdr:
srate: 23.04
tx_gain: 25
rx_gain: 25
amplitude_control:
tx_gain_backoff: 22
cell_cfg:
dl_arfcn: 632628
@@ -44,8 +42,8 @@ cell_cfg:
nof_cell_csi_res: 0
log:
filename: stdout
all_level: info
filename: gnb.log
all_level: debug
pcap:
mac_enable: false

View File

@@ -20,8 +20,6 @@ ru_sdr:
srate: 61.44
tx_gain: 25
rx_gain: 25
amplitude_control:
tx_gain_backoff: 22
cell_cfg:
dl_arfcn: 632628
@@ -46,8 +44,8 @@ cell_cfg:
nof_cell_csi_res: 0
log:
filename: stdout
all_level: info
filename: gnb.log
all_level: debug
pcap:
mac_enable: false

View File

@@ -1,52 +0,0 @@
# SPDX-License-Identifier: MIT
services:
oai-gnb:
image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop}
container_name: rfsim5g-oai-gnb
cap_drop:
- ALL
cap_add:
- SYS_NICE
environment:
USE_ADDITIONAL_OPTIONS: --phy-test --device.name vrtsim --vrtsim.role server -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
ipc: host
volumes:
- ../../conf_files/gnb.band79.106prb.vrtsim.phytest-dora.conf:/opt/oai-gnb/etc/gnb.conf
- rrc.config:/opt/oai-gnb/
- tmp_data:/tmp/
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
oai-nr-ue:
image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop}
container_name: rfsim5g-oai-nr-ue
cap_drop:
- ALL
cap_add:
- SYS_NICE
environment:
USE_ADDITIONAL_OPTIONS: --phy-test --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw --device.name vrtsim --vrtsim.role client -q --log_config.global_log_options level,nocolor,time
ASAN_OPTIONS: detect_leaks=0
devices:
- /dev/net/tun:/dev/net/tun
ipc: host
volumes:
- ../../conf_files/nrue.uicc.conf:/opt/oai-nr-ue/etc/nr-ue.conf
- rrc.config:/opt/oai-nr-ue/etc/rrc/
- tmp_data:/tmp/
depends_on:
- oai-gnb
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
volumes:
rrc.config:
tmp_data:

View File

@@ -1,6 +1,18 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
OAI O-RAN 7.2 Front-haul Docker Compose
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="../../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI O-RAN 7.2 Front-haul Docker Compose</font></b>
</td>
</tr>
</table>
![Docker deploy 7.2](../../../doc/images/docker-deploy-oai-7-2.png)

View File

@@ -43,8 +43,6 @@ Options:
Sets build directory (will be <oai-root>/cmake_targets/<build-dir>/build)
--build-e2
Enable the the E2 Agent
--build-e3
Enable the the E3 Agent
-I | --install-external-packages
Installs required packages such as LibXML, asn1.1 compiler, ...
This option will require root password
@@ -145,10 +143,6 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -DE2_AGENT=ON"
shift
;;
--build-e3 )
CMAKE_CMD="$CMAKE_CMD -DE3_AGENT=ON"
shift
;;
-I | --install-external-packages)
INSTALL_EXTERNAL=1
echo_info "Will install external packages"
@@ -207,7 +201,6 @@ function main() {
shift;;
--nrRU)
NRRU=1
CMAKE_CMD="$CMAKE_CMD -DOAI_RU_FRONTHAUL=ON"
TARGET_LIST="$TARGET_LIST nr-oru"
echo_info "Will compile NR O-RU"
shift;;

View File

@@ -6,7 +6,7 @@
# Finds the xran library. Note that the library number is as follows:
# - oran_e_maintenance_release_v1.5 -> 5.1.6
# - oran_f_release_v1.3 -> 6.1.4
# - oran_k_release_v1.3 -> 11.1.3
# - oran_k_release_v1.1 -> 11.1.1
#
# Required options
# ^^^^^^^^^^^^^^^^

View File

@@ -465,6 +465,7 @@ install_asn1c_from_source(){
echo_info "\nInstalling ASN1."
$SUDO $INSTALLER -y install bison flex
$SUDO rm -rf /tmp/asn1c
# GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c
git clone https://github.com/mouse07410/asn1c /tmp/asn1c
cd /tmp/asn1c
#git checkout vlm_master
@@ -494,8 +495,8 @@ install_simde_from_source(){
if [[ -v SIMDE_VERSION ]]; then
git checkout -f $SIMDE_VERSION
else
# At time of writing, last working commit for OAI: 1c68d9a
git checkout 1c68d9ad60bf63f3fb527c4ee3b2319d828ffcc6
# At time of writing, last working commit for OAI: c7f26b7
git checkout c7f26b73ba8e874b95c2cec2b497826ad2188f68
fi
# Showing which version is used
git log -n1

View File

@@ -39,9 +39,8 @@ typedef enum { NON_DYNAMIC, DYNAMIC } fiveQI_t;
/* 5QI (5G QoS Identifier) - 3GPP TS 23.501 §5.7.2.1
* Range: 0..255
* - Standardized 5QI values: have one-to-one mapping to standardized 5G QoS characteristics (Table 5.7.4-1)
* - Pre-configured 5QI values: pre-configured in the AN (not in Table 5.7.4-1)
* - Dynamically assigned 5QI values: require signaling of QoS characteristics as part of QoS profile
* OAI implements standardized non-dynamic 5QI only. */
* - Pre-configured 5QI values: pre-configured in the AN
* - Dynamically assigned 5QI values: require signaling of QoS characteristics as part of QoS profile */
#define MIN_FIVEQI 0
#define MAX_STANDARDIZED_FIVEQI 90
#define MAX_FIVEQI 255

View File

@@ -9,3 +9,5 @@ The configuration module provides an api that other oai components can use to ge
* [runtime usage](config/rtusage.md)
* [developer usage](config/devusage.md)
* [module architecture](config/arch.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -14,9 +14,9 @@ As a developer you may need to look at these sections:
Whatever your need is, configuration module usage examples can be found in oai sources:
* complex example, using all the configuration module functionalities, including parameter checking:
[NB-IoT configuration code](../../../../openair2/ENB_APP/NB_IoT_config.c) and [NB-IoT configuration include file](../../../../openair2/ENB_APP/NB_IoT_paramdef.h)
* very simple example, just reading a parameter set corresponding to a dedicated section: the telnetsrv_autoinit function in [common/utils/telnetsrv/telnetsrv.c, around line 726](../../../../common/utils/telnetsrv/telnetsrv.c)
* an example with run-time definition of parameters, in the logging sub-system: the log_getconfig function at the top of [openair2/UTIL/LOG/log.c](../../../../common/utils/LOG/log.c)
[NB-IoT configuration code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_config.c) and [NB-IoT configuration include file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_paramdef.h)
* very simple example, just reading a parameter set corresponding to a dedicated section: the telnetsrv_autoinit function in [common/utils/telnetsrv/telnetsrv.c, around line 726](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv.c#L726)
* an example with run-time definition of parameters, in the logging sub-system: the log_getconfig function at the top of [openair2/UTIL/LOG/log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/UTIL/LOG/log.c)
[Configuration module home](../config.md)

View File

@@ -82,7 +82,7 @@ for(int i=0 ; i < sizeof(someoptions)/sizeof(paramdesc_t) ; i ++) {
}
....
```
When you need a specific verification algorithm, you can provide your own verification function and use it in place of the available ones, in the `checkedparam_t` union. If no existing structure definition match your need, you can enhance the configuration module. You then have to add a new verification function in ../../../../../common/config/config_userapi.c and add a new structure definition in the `checkedparam_t` type defined in ../../../../../common/config/config_paramdesc.h
When you need a specific verification algorithm, you can provide your own verification function and use it in place of the available ones, in the `checkedparam_t` union. If no existing structure definition match your need, you can enhance the configuration module. You then have to add a new verification function in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.c and add a new structure definition in the `checkedparam_t` type defined in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h
[Configuration module developer main page](../../config/devusage.md)
[Configuration module home](../../config.md)

View File

@@ -45,7 +45,7 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int
## utility functions and macros
The configuration module also defines APIs to access the `paramdef_t` and `configmodule_interface_t` fields. They are listed in the configuration module [include file `common/config/config_userapi.h`](../../../../common/config/config_userapi.h)
The configuration module also defines APIs to access the `paramdef_t` and `configmodule_interface_t` fields. They are listed in the configuration module [include file `common/config/config_userapi.h`](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.h)
[Configuration module developer main page](../../config/devusage.md)
[Configuration module home](../../config.md)

View File

@@ -1,7 +1,7 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
# `paramdef_t`structure
It is defined in include file [ common/config/config_paramdesc.h ](../../../../../common/config/config_paramdesc.h#L103). This structure is used by developers to describe parameters and by the configuration module to return parameters value. A pointer to a `paramdef_t` array is passed to `config_get` and `config_getlist` calls to instruct the configuration module what parameters it should read.
It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L103). This structure is used by developers to describe parameters and by the configuration module to return parameters value. A pointer to a `paramdef_t` array is passed to `config_get` and `config_getlist` calls to instruct the configuration module what parameters it should read.
| Fields | Description | I/O |
|:-----------|:------------------------------------------------------------------|----:|
@@ -32,7 +32,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](../../../../.
# `paramlist_def_t`structure
It is defined in include file [ common/config/config_paramdesc.h ](../../../../../common/config/config_paramdesc.h#L160).
It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160).
It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters.
| Fields | Description | I/O |
@@ -42,7 +42,7 @@ It is used as an argument to `config_getlist` calls, to get values of multiple o
| `numelt` | Number of items in the `paramarray` field | O |
# `checkedparam_t` union
It is defined in include file [ common/config/config_paramdesc.h ](../../../../../common/config/config_paramdesc.h#L62).
It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L62).
This union of structures is used to provide a parameter checking mechanism. Each `paramdef_t` instance may include a pointer to a `checkedparam_t`structure which is then used by the configuration module to check the value it got from the config source.
Each structure in the union provides one parameter verification method, which returns `-1` when the verification fails. Currently the following structures are defined in the `checkedparam_t` union:

View File

@@ -45,8 +45,6 @@
#define NR_MAX_NB_PDU_SESSIONS (256)
#define NR_MAX_NB_ALLOWED_SNSSAI (8) /* Maximum number of allowed S-NSSAI in TS 38.413 */
#define MAX_DRBS_PER_UE (32) /* Maximum number of Data Radio Bearers per UE
* defined for NGAP in TS 38.413 - maxnoofDRBs */
#define MAX_PDUS_PER_UE (8) /* Maximum number of PDU Sessions per UE */
@@ -57,8 +55,6 @@
/** Maximum number of Paging Occasions per Paging Frame (TS 38.331 PCCH-Config) */
#define NR_PCCH_MAX_PO 4
#define NR_PHYS_CELL_ID_MAX 1007 /* Maximum Physical Cell ID (0..1007) */
#define NB_RB_MBMS_MAX (29 * 16) /* 29 = LTE_maxSessionPerPMCH + 16 = LTE_maxServiceCount from LTE_asn_constant.h */
#define NB_RAB_MAX 11 /* from LTE_maxDRB in LTE_asn_constant.h */
@@ -82,7 +78,7 @@
#define MAX_QOS_FLOWS 64
/** Maximum number of PagingRecords in one PCCH Paging message (TS 38.331) */
#define NR_PCCH_MAX_PAGING_RECORDS 32
#define NR_PCCH_MAX_PAGING_RECORDS 16
// SDAP/5G NAS NOS1
#define DEFAULT_NOS1_PDU_ID 10

View File

@@ -15,3 +15,5 @@ The main drawback is a performance cost at init time, when loading libraries.
* [runtime usage](loader/rtusage.md)
* [developer usage](loader/devusage.md)
* [module architecture](loader/arch.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -2,8 +2,8 @@
# loader source files
The oai shared library loader is implemented in two source files, located in `common/utils/`:
1. [load_module_shlib.c](../../load_module_shlib.c) contains the loader implementation
1. [load_module_shlib.h](../../load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes.
The oai shared library loader is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils)
1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation
1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes.
[loader home page](../loader.md)

View File

@@ -1,6 +1,6 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
Loader API is defined in the [common/utils/load_module_shlib.h](../../load_module_shlib.h) include file.
Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file.
```c
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
```

View File

@@ -1,7 +1,7 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
# `loader_shlibfunc_t`structure
It is defined in include file [ common/util/load_module_shlib.h ](../../load_module_shlib.h#L38). This structure is used to list the symbols that should be searched by the loader when calling the `load_module_shlib` function.
It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h#L38). This structure is used to list the symbols that should be searched by the loader when calling the `load_module_shlib` function.
| Fields | Description | I/O |
|:-----------|:------------------------------------------------------------------|----:|

View File

@@ -11,7 +11,7 @@ LOG_D(<component>,<format>,<argument>,...)
LOG_T(<component>,<format>,<argument>,...)
)
```
these macros are used in place of the printf C function. The additional ***component*** parameter identifies the functional module which generates the message. At run time, the message will only be printed if the configured log level for the component is greater or equal than the macro level used in the code.
these macros are used in place of the printf C function. The additionnal ***component*** parameter identifies the functionnal module which generates the message. At run time, the message will only be printed if the configured log level for the component is greater or equal than the macro level used in the code.
| macro | level letter | level value | level name |
|:---------|:---------------|:---------------|----------------:|
@@ -22,7 +22,7 @@ these macros are used in place of the printf C function. The additional ***compo
| LOG_D | D | 4 | debug |
| LOG_T | T | 5 | trace |
component list is defined as an `enum` in [log.h](../log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](../../T/T_messages.txt).
component list is defined as an `enum` in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/T/T_messages.txt).
Most oai sources are including LOG macros.
@@ -42,6 +42,7 @@ if ( LOG_DEBUGFLAG(<flag>) {
......................
}
```
[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396)
#### memory dump macros
```C
@@ -59,6 +60,7 @@ LOG_M(.............
log_dump(...
}
[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205)
#### matlab format dump
```C
LOG_M(file, vector, data, len, dec, format)
@@ -72,7 +74,8 @@ LOG_M(file, vector, data, len, dec, format)
| dec| int | length of each data item.Interpretation depends on format|
|format| int | defines the type of data to be dumped|
This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in [log.c](../log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)**
This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)**
[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205)
#### hexadecimal format dump
```C
@@ -83,14 +86,15 @@ dumps a memory region if the corresponding debug flag `f` is set as explained he
|argument| type| description |
|:-----------|:-------|-----------------:|
| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments |
|f |int |flag used to filter the dump depending on the logs configuration. flag list is defined by the LOG_MASKMAP_INIT macro in [log.h](../log.h) |
|f |int |flag used to filter the dump depending on the logs configuration. flag list is defined by the LOG_MASKMAP_INIT macro in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) |
|b| void *| pointer to the memory to be dumpped |
|s | int | length of the data to be dumpped in char|
| x...| printf format and arguments| text string to be printed at the top of the dump|
This macro can be used to conditionaly dump a buffer, bytes by bytes, giving the integer value of each byte in hexadecimal form.
[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181)
This macro points to the `log_dump` function, implemented in [log.c](../log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro
This macro points to the `log_dump` function, implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro
```C
LOG_UDUMPMSG(c, b, s, f, x...)
@@ -103,5 +107,8 @@ LOG_UDUMPMSG(c, b, s, f, x...)
|f| int | format of dumped data LOG_DUMP_CHAR or LOG_DUMP_DOUBLE|
| x...| printf format and arguments| text string to be printed at the top of the dump|
[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974)
[logging facility developer main page](devusage.md)
[logging facility main page](log.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -11,3 +11,4 @@ The logging facility doesn't create any thread, all api's are executed in the co
Data used by the logging utility are defined by the `log_t` structure which is allocated at init time, when calling the `logInit` function.
[logging facility main page](log.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -39,7 +39,7 @@ CLEAR_LOG_DUMP(flag)
```
These macros are used to set or clear the corresponding bit flag, trigerring the activation or un-activation of conditional code or memory dumps generation.
Example of using the logging utility APIs can be found, for initialization and cleanup, in [lte-softmodem.c](../../../../executables/lte-softmodem.c) and in the [telnet server log command implementation](../../telnetsrv/telnetsrv_proccmd.c) for a complete access to the logging facility features.
Example of using the logging utility APIs can be found, for initialization and cleanup, in [lte-softmodem.c](../../../../targets/RT/USER/lte-softmodem.c) and in the [telnet server log command implementation](../../telnetsrv/telnetsrv_proccmd.c) for a complete access to the logging facility features.
#### components and debug flags definitions
@@ -48,3 +48,4 @@ To add a flag than can then be used for adding conditional code or memory dumps
[logging facility developer main page](devusage.md)
[logging facility main page](log.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -18,3 +18,5 @@ By default, this facility is included at build-time and activated at run-time. T
* [developer usage](devusage.md)
* [module architecture](arch.md)
* [lttng usage](lttng_logs.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -276,3 +276,4 @@ The telnet server includes a `log` command which can be used to dymically modify
[telnet server ***softmodem log*** commands](../../telnetsrv/DOC/telnetlog.md)
[logging facility main page](log.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -155,7 +155,6 @@ static const char *const flag_name[] = {FOREACH_FLAG(FLAG_TEXT) ""};
COMP_DEF(NFAPI_PNF, log) \
COMP_DEF(ITTI, log) \
COMP_DEF(UTIL, log) \
COMP_DEF(E3AP, log) \
COMP_DEF(MAX_LOG_PREDEF_COMPONENTS, )
#define COMP_ENUM(comp, file_extension) comp,

View File

@@ -434,27 +434,6 @@ ID = LEGACY_MAC_TRACE
GROUP = ALL:LEGACY_MAC:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_E3AP_INFO
DESC = E3AP legacy logs - info level
GROUP = ALL:LEGACY_E3AP:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_E3AP_ERROR
DESC = E3AP legacy logs - error level
GROUP = ALL:LEGACY_E3AP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
ID = LEGACY_E3AP_WARNING
DESC = E3AP legacy logs - warning level
GROUP = ALL:LEGACY_E3AP:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_E3AP_DEBUG
DESC = E3AP legacy logs - debug level
GROUP = ALL:LEGACY_E3AP:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_E3AP_TRACE
DESC = E3AP legacy logs - trace level
GROUP = ALL:LEGACY_E3AP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_NR_MAC_INFO
DESC = NR_MAC legacy logs - info level
GROUP = ALL:LEGACY_NR_MAC:LEGACY_GROUP_INFO:LEGACY

View File

@@ -70,8 +70,7 @@ static __attribute__((always_inline)) inline int count_bits64(uint64_t v)
static __attribute__((always_inline)) inline int count_bits64_with_mask(uint64_t v, int start, int num)
{
AssertFatal(start >= 0 && num > 0 && start + num <= 64, "Invalid range: start=%d num=%d for 64 bits mask\n", start, num);
uint64_t mask = (num == 64 ? ~0ULL : (1ULL << num) - 1) << start;
uint64_t mask = ((1LL << num) - 1) << start;
return count_bits64(v & mask);
}

View File

@@ -257,9 +257,11 @@ uint32_t nr_timer_remaining_time(const NR_timer_t *timer);
int set_default_nta_offset(frequency_range_t freq_range, uint32_t samples_per_subframe);
static inline int get_num_dmrs(uint16_t dmrs_mask)
static inline int get_num_dmrs(uint16_t dmrs_mask )
{
return __builtin_popcount(dmrs_mask);
int num_dmrs=0;
for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1);
return(num_dmrs);
}
void warn_higher_threequarter_fs(const int n_rb, const int mu);

View File

@@ -40,9 +40,6 @@ typedef struct ShmTDIQChannel_s {
ShmTDIQChannel *shm_td_iq_channel_create(const char *name, int num_tx_ant, int num_rx_ant)
{
// Unlink any stale shared memory segment first to ensure we start fresh and reclaim space
shm_unlink(name);
// Create shared memory segment
int fd = shm_open(name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
AssertFatal(fd != -1, "shm_open failed: %s\n", strerror(errno));
@@ -99,48 +96,29 @@ ShmTDIQChannel *shm_td_iq_channel_connect(const char *name, int timeout_in_secon
{
// Create shared memory segment
int fd = -1;
double timeout_in_uS = timeout_in_seconds * 1000000.0;
while (timeout_in_uS > 0 && fd == -1) {
while (timeout_in_seconds > 0 && fd == -1) {
for (int i = 0; i < 1000; i++) {
fd = shm_open(name, O_RDWR, S_IRUSR | S_IWUSR);
if (fd != -1) {
break;
}
usleep(1000);
timeout_in_uS -= 1000;
}
timeout_in_seconds--;
if (fd == -1) {
printf("Waiting for server to create shared memory segment\n");
}
}
AssertFatal(fd != -1, "shm_open() failed: errno %d, %s", errno, strerror(errno));
// Map just the header first to wait for initialization
ShmTDIQChannelData *shm_ptr = mmap(NULL, sizeof(ShmTDIQChannelData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shm_ptr == MAP_FAILED) {
perror("mmap header");
exit(1);
}
// Wait until server initializes the segment
while (timeout_in_uS > 0 && shm_ptr->magic != SHM_MAGIC_NUMBER) {
usleep(1000);
timeout_in_uS -= 1000;
}
AssertFatal(shm_ptr->magic == SHM_MAGIC_NUMBER, "Timeout waiting for server to initialize shared memory segment\n");
// Now that it's initialized, ftruncate has finished, so we can get the actual size
struct stat buf;
fstat(fd, &buf);
size_t total_size = buf.st_size;
// Unmap the temporary header mapping
munmap(shm_ptr, sizeof(ShmTDIQChannelData));
// Map the entire shared memory segment
shm_ptr = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// Map shared memory segment to address space
ShmTDIQChannelData *shm_ptr = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shm_ptr == MAP_FAILED) {
perror("mmap full");
perror("mmap");
exit(1);
}
@@ -156,6 +134,10 @@ ShmTDIQChannel *shm_td_iq_channel_connect(const char *name, int timeout_in_secon
channel->nb_rx_ant = channel->data->num_antennas_tx;
printf("\033[38;5;208mnb_tx_ant, nb_rx_ant: %d, %d\n\033[0m", channel->nb_tx_ant, channel->nb_rx_ant);
channel->type = IQ_CHANNEL_TYPE_CLIENT;
while (shm_ptr->magic != SHM_MAGIC_NUMBER) {
printf("Waiting for server to initialize shared memory\n");
sleep(1);
}
close(fd);
return channel;
}
@@ -256,7 +238,7 @@ int shm_td_iq_channel_wait(ShmTDIQChannel *channel, uint64_t timestamp, uint64_t
fprintf(stderr, "Error: clock_gettime failed: %s\n", strerror(errno));
return 1;
}
ts.tv_sec += timeout_uS / 1000000; // Convert microseconds to seconds
ts.tv_nsec += (timeout_uS % 1000000) * 1000; // Convert remaining microseconds to nanoseconds

View File

@@ -31,6 +31,7 @@
#include <arpa/inet.h>
#include <common/utils/assertions.h>
#include <common/utils/LOG/log.h>
#include "common_lib.h"
#ifdef T
#undef T

View File

@@ -2,7 +2,7 @@
# code example of adding a command to the telnet server
The following example is extracted from [the oai `openair1/PHY/CODING/coding_load.c` file](../../../../openair1/PHY/CODING/coding_load.c).
The following example is extracted from [the oai `openair1/PHY/CODING/coding_load.c` file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c).
```c
/*

View File

@@ -21,7 +21,7 @@ The telnet server provides an API which can be used by any oai component to add
# telnet server source files
telnet server source files are located in `common/utils/telnetsrv/`
telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv)
1. [telnetsrv.c](../telnetsrv.c) contains the telnet server implementation, including the implementation of the `telnet` CLI command. This implementation is compatible with all softmodem executables and is in charge of loading any additional `libtelnetsrv_<app> .so` containing code specific to the running executables.
1. [telnetsrv.h](../telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server.

View File

@@ -92,3 +92,4 @@ Connection closed by foreign host.
[oai telnetserver home](telnetsrv.md)
[oai telnetserver usage home](telnetusage.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -6,3 +6,5 @@ The oai embedded telnet server is an optional monitoring and debugging tool. It
* [Adding commands to the oai telnet server](telnetaddcmd.md)
* [telnet server architecture ](telnetarch.md)
* [on the telnet O1 module](telneto1.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -9,7 +9,3 @@ add_executable(test_fsn test_fsn.cpp)
add_dependencies(tests test_fsn)
target_link_libraries(test_fsn PRIVATE utils GTest::gtest)
add_test(NAME test_fsn COMMAND ./test_fsn)
add_executable(test_bits test_bits.c)
add_dependencies(tests test_bits)
add_test(NAME test_bits COMMAND ./test_bits)

View File

@@ -1,224 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <bits.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
/* ── test harness ── */
static int g_failures = 0;
#define ARRSIZE 9
#define BITS_PER_WORD 32
#define TOTAL_BITS (ARRSIZE * BITS_PER_WORD)
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
abort();
}
static inline void set_bit_in_array(uint32_t *arr, int bit_pos)
{
arr[bit_pos / BITS_PER_WORD] |= 1u << (bit_pos % BITS_PER_WORD);
}
static void run_test(const char *name, int result, int expected)
{
if (result != expected) {
fprintf(stderr, "FAIL [%s]: got %d, want %d\n", name, result, expected);
g_failures++;
} else {
printf("PASS [%s]\n", name);
}
}
static void test_get_first_bit_index_mask(void)
{
/* --- no bits set --- */
uint32_t zeros[ARRSIZE] = {0};
run_test("firstbit_all_zeros", get_first_bit_index_mask(zeros, ARRSIZE, 0, TOTAL_BITS), -1);
uint32_t arr[ARRSIZE];
/* --- random single hit at a random position --- */
int num_trials = 5;
for (int t = 0; t < num_trials; t++) {
int bit_pos = rand() % (TOTAL_BITS); /* random bit in [0, 128) */
char test_name[64];
snprintf(test_name, sizeof(test_name), "firstbit_single_hit_bit%d", bit_pos);
memset(arr, 0, sizeof(arr));
set_bit_in_array(arr, bit_pos);
run_test(test_name, get_first_bit_index_mask(arr, ARRSIZE, 0, TOTAL_BITS), bit_pos);
}
/* --- random multi-hit with random window --- */
int multi_trials = 5;
for (int t = 0; t < multi_trials; t++) {
memset(arr, 0, sizeof(arr));
int from_bit = rand() % (TOTAL_BITS);
int num_bits = 1 + rand() % (TOTAL_BITS - from_bit); /* at least 1 bit wide */
int window_end = from_bit + num_bits;
int min_pos = -1;
int num_bits_set = 5 + rand() % 20;
for (int b = 0; b < num_bits_set; b++) {
int bit_pos = from_bit + rand() % num_bits; /* confined to the window */
set_bit_in_array(arr, bit_pos);
if (min_pos == -1 || bit_pos < min_pos)
min_pos = bit_pos;
}
/* put some bits outside the window to test they are ignored in some trial */
if (from_bit > 0 && t % 2) {
int bit_pos = rand() % from_bit; /* before the window */
set_bit_in_array(arr, bit_pos);
}
if (window_end < TOTAL_BITS && t % 2) {
int bit_pos = window_end + rand() % (TOTAL_BITS - window_end); /* after */
set_bit_in_array(arr, bit_pos);
}
char test_name[64];
snprintf(test_name, sizeof(test_name), "firstbit_multi_hit_trial%d_from%d_num%d_min%d", t, from_bit, num_bits, min_pos);
run_test(test_name, get_first_bit_index_mask(arr, ARRSIZE, from_bit, num_bits), min_pos);
}
}
static void test_get_last_bit_index(void)
{
/* --- no bits set --- */
uint32_t zeros[ARRSIZE] = {0};
run_test("lastbit_all_zeros", get_last_bit_index(zeros, ARRSIZE), -1);
uint32_t arr[ARRSIZE];
/* --- random single hit at a random position --- */
int num_trials = 5;
for (int t = 0; t < num_trials; t++) {
int bit_pos = rand() % (TOTAL_BITS);
char test_name[64];
snprintf(test_name, sizeof(test_name), "lastbit_single_hit_bit%d", bit_pos);
memset(arr, 0, sizeof(arr));
set_bit_in_array(arr, bit_pos);
run_test(test_name, get_last_bit_index(arr, ARRSIZE), bit_pos);
}
/* --- random multi-hit: scattered bits, must return the maximum --- */
int multi_trials = 5;
for (int t = 0; t < multi_trials; t++) {
memset(arr, 0, sizeof(arr));
int max_pos = -1;
int num_bits_set = 5 + rand() % 20;
for (int b = 0; b < num_bits_set; b++) {
int bit_pos = rand() % (TOTAL_BITS);
set_bit_in_array(arr, bit_pos);
if (bit_pos > max_pos)
max_pos = bit_pos;
}
char test_name[64];
snprintf(test_name, sizeof(test_name), "lastbit_multi_hit_trial%d_max%d", t, max_pos);
run_test(test_name, get_last_bit_index(arr, ARRSIZE), max_pos);
}
}
static void fisher_yates_shuffle(int *positions, int total, int n)
{
/* partial shuffle: pick n distinct random positions from [0, total) */
/* see https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm */
for (int i = 0; i < n; i++) {
int j = i + rand() % (total - i);
int tmp = positions[i];
positions[i] = positions[j];
positions[j] = tmp;
}
}
static void test_count_bits(void)
{
uint32_t arr[ARRSIZE];
/* --- no bits set --- */
uint32_t zeros[ARRSIZE] = {0};
run_test("countbits_all_zeros", count_bits(zeros, ARRSIZE), 0);
/* --- all bits set --- */
uint32_t all_set[ARRSIZE];
memset(all_set, 0xFF, sizeof(all_set));
run_test("countbits_all_set", count_bits(all_set, ARRSIZE), TOTAL_BITS);
/* --- random trials: set exactly N random bits, expect count N --- */
int positions[TOTAL_BITS];
for (int i = 0; i < TOTAL_BITS; i++)
positions[i] = i;
int num_trials = 5;
for (int t = 0; t < num_trials; t++) {
memset(arr, 0, sizeof(arr));
int n = 1 + rand() % TOTAL_BITS;
fisher_yates_shuffle(positions, TOTAL_BITS, n);
for (int i = 0; i < n; i++)
set_bit_in_array(arr, positions[i]);
char test_name[64];
snprintf(test_name, sizeof(test_name), "countbits_trial%d_n%d", t, n);
run_test(test_name, count_bits(arr, ARRSIZE), n);
}
}
void test_count_bits64_with_mask(void)
{
/* --- zero value --- */
run_test("countbits64_zero_value", count_bits64_with_mask(0ULL, 0, 64), 0);
/* --- all bits set, full window --- */
run_test("countbits64_all_set_full_window", count_bits64_with_mask(0xFFFFFFFFFFFFFFFFULL, 0, 64), 64);
/* --- all bits set, window filters correctly --- */
run_test("countbits64_all_set_window_16_from_8", count_bits64_with_mask(0xFFFFFFFFFFFFFFFFULL, 8, 16), 16);
/* --- random trials: set exactly N bits within window, expect count N --- */
int num_trials = 5;
for (int t = 0; t < num_trials; t++) {
int start = rand() % 64;
int num = 1 + rand() % (64 - start);
int window_end = start + num;
/* initialise positions to the window [start, start+num) */
int positions[64];
for (int i = 0; i < num; i++)
positions[i] = start + i;
int n = 1 + rand() % num;
fisher_yates_shuffle(positions, num, n);
uint64_t v = 0;
for (int i = 0; i < n; i++)
v |= 1ULL << positions[i];
/* put bits outside the window on odd trials */
if (t % 2) {
if (start > 0)
v |= 1ULL << (rand() % start);
if (window_end < 64)
v |= 1ULL << (window_end + rand() % (64 - window_end));
}
char test_name[64];
snprintf(test_name, sizeof(test_name), "countbits64_trial%d_start%d_num%d_n%d", t, start, num, n);
run_test(test_name, count_bits64_with_mask(v, start, num), n);
}
}
int main(void)
{
srand((unsigned)time(NULL));
test_get_first_bit_index_mask();
test_get_last_bit_index();
test_count_bits();
test_count_bits64_with_mask();
if (g_failures > 0) {
fprintf(stderr, "\n%d test(s) FAILED.\n", g_failures);
return 1;
}
printf("\nAll tests passed.\n");
return 0;
}

View File

@@ -294,7 +294,6 @@ int tuntap_generate_ue_ifname(char *ifname, int flag, int instance_id, int pdu_s
char pdu_session_string[10];
snprintf(pdu_session_string, sizeof(pdu_session_string), "p%d", pdu_session_id);
const char *basename = flag == IFF_TUN ? "oaitun_ue" : "oaitap_ue";
// ifname: oaitun_ue<ue_id+1>[p<pdu_session_id>] when not default
return snprintf(ifname, IFNAMSIZ, "%s%d%s", basename, instance_id + 1, pdu_session_id == -1 ? "" : pdu_session_string);
}

View File

@@ -5,3 +5,5 @@ The oai web server is an optional monitoring and debugging tool. Purpose is to g
* [Using the web server](websrvuse.md)
* [enhancing the webserver](websrvdev.md)
* [web server architecture ](websrvarch.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -17,19 +17,13 @@ Key 5GS NAS messages:
## OAI Implementation Status
The following table lists NAS messages with dedicated `encode_*` / `decode_*` codecs under
`openair3/NAS/NR_UE/5GS/` (`5GMM/MSG`, `5GSM/MSG`). Unit test entries refer to
[`nas_lib_test.c`](../openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c), most are encode/decode round-trips.
The following table lists implemented NAS messages and whether there is an encoder or decoder function, and if a corresponding unit test exists.
| Type | Message | Encoding | Decoding | Unit test |
|-------|-------------------------------------------|----------|----------|------------|
| 5GMM | Service Request | yes | yes | yes |
| 5GMM | Service Accept | yes | yes | yes |
| 5GMM | Service Reject | yes | yes | yes |
| 5GMM | Authentication Failure | yes | yes | yes |
| 5GMM | Authentication Reject | yes | yes | yes |
| 5GMM | Security Mode Reject | yes | yes | yes |
| 5GMM | Identity Request | no | yes | no |
| 5GMM | Authentication Response | yes | no | no |
| 5GMM | Identity Response | yes | no | no |
| 5GMM | Security Mode Complete | yes | no | no |
@@ -44,23 +38,6 @@ The following table lists NAS messages with dedicated `encode_*` / `decode_*` co
| 5GSM | PDU Session Establishment Request | yes | no | no |
| 5GSM | PDU Session Establishment Accept | no | yes | no |
### Runtime-handled messages
These network-originated messages are handled in [`nr_nas_msg.c`](../openair3/NAS/NR_UE/nr_nas_msg.c):
* Authentication Request
* Security Mode Command
* Downlink NAS Transport
* Deregistration Accept (UE originating)
* Registration Reject
* PDU Session Establishment Reject
## Integration testing
End-to-end attach can be tested with the [NR UE NAS simulator](../tests/nr-ue-nas-simulator/README.md),
which runs the OAI UE NAS stack and gNB NGAP against the AMF, forwarding NAS PDUs without PHY/MAC/RLC.
Use `nas_lib_test` for isolated codec round-trips.
### Code Structure
[openair3/NAS/NR_UE/nr_nas_msg.c](../openair3/NAS/NR_UE/nr_nas_msg.c):

View File

@@ -20,7 +20,7 @@ The hardware on which we have tried this tutorial:
- These are not minimum hardware requirements. This is the configuration of our
servers. The NIC card should support hardware PTP time stamping.
- Starting from tag
[2025.w13](https://github.com/duranta-project/openairinterface5g/releases/tag/2025.w13)
[2025.w13](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/2025.w13?ref_type=tags)
of OAI, we are only testing with the Grace Hopper server.
PTP enabled switches and grandmaster clock we have tested with:
@@ -60,7 +60,7 @@ To set up the L1 and install the components manually refer to this [instructions
**Note**:
- To configure the Gigabyte server please refer to these
[instructions](https://github.com/duranta-project/openairinterface5g/blob/2025.w13/doc/Aerial_FAPI_Split_Tutorial.md)
[instructions](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/2025.w13/doc/Aerial_FAPI_Split_Tutorial.md)
- The last release to support the Gigabyte server is **Aerial CUDA-Accelerated
RAN 24-1**.
@@ -183,7 +183,7 @@ WantedBy=multi-user.target
If it's not already cloned, the first step is to clone OAI repository
```bash
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g/
```
@@ -224,7 +224,8 @@ With the nvIPC sources in the project directory, the L2 docker image can be buil
In order to build the target image (`oai-gnb-aerial`), first you should build a
common shared image (`ran-base`). For more information about `docker build`
files please refer to this [tutorial](../docker/README.md)
files please refer to this
[tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/ARC1.7_integration/docker/README.md?ref_type=heads)
```bash
~$ cd ~/openairinterface5g/
@@ -237,24 +238,26 @@ files please refer to this [tutorial](../docker/README.md)
### Adapt the OAI-gNB configuration file to your system/workspace
Edit the [OAI gNB configuration file](../ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf)
Edit the [OAI gNB configuration file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/ci-scripts/conf_files/gnb-vnf.sa.band78.273prb.aerial.conf?ref_type=heads)
and check the following parameters:
* `gNBs` section
* The PLMN section shall match the one defined in the AMF
* To calculate the `absoluteFrequencySSB` and `dl_absoluteFrequencyPointA`,
please follow these [instructions](./gNB_frequency_setup.md)
please follow these
[instructions](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/gNB_frequency_setup.md)
* `amf_ip_address` shall be the correct AMF IP address in your system
* `GNB_IPV4_ADDRESS_FOR_NG_AMF` shall match your DU N2 interface IP address
* `GNB_IPV4_ADDRESS_FOR_NGU` shall match your DU N3 interface IP address
The default amf_ip_address:ipv4 value is 192.168.70.132, when installing the
CN5G following [this tutorial](./NR_SA_Tutorial_OAI_CN5G.md)
CN5G following [this
tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_OAI_CN5G.md)
Both `GNB_IPV4_ADDRESS_FOR_NG_AMF` and `GNB_IPV4_ADDRESS_FOR_NGU` need to be
set to the IP address of the NIC referenced previously.
**Note**: If the Core Network is running on the same server, 3 cores should be
allocated to it. 2 for the UPF and 1 core shared between the remaining services as shown
allocated to it. 2 for the UPF and 1 for the all the remaining services as shown
below.
```patch

View File

@@ -51,7 +51,7 @@ PROJECT_BRIEF = "Full experimental OpenSource LTE and NR implementation
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO =
PROJECT_LOGO = @CMAKE_SOURCE_DIR@/doc/images/oai_logo.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is

View File

@@ -146,9 +146,8 @@ These modes of operation are supported:
- evaluation of CQI report
- MAC scheduling of SR reception
- Paging (PCCH/P-RNTI)
- CN paging records queued
- PF/PO dequeue from SIB1 PCCH-Config
- PCCH encoded at the UE's PO
- Build and enqueue PCCH paging SDUs
- PF/PO-based paging occasion scheduling from SIB1 PCCH config
- Type2 common search-space based P-RNTI PDCCH + PDSCH scheduling for PCCH
- Intra-frequency handover
- Inter-frequency handover
@@ -489,8 +488,8 @@ These modes of operation are supported:
* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16
* 5GMM (5G Mobility Management) messages:
- Service Request/Accept/Reject (Network-triggered Service Request TS 23.502 §4.2.3.3,
UE-Triggered Service Request after paging, TS 23.502 §4.2.3.2)
- Service Request/Accept/Reject
- Network-triggered Service Request on paging
- Identity Request/Response
- Authentication Request/Response
- Security Mode Command/Complete
@@ -712,6 +711,9 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions
- EMM attach/detach, authentication, tracking area update, and more
- ESM default/dedicated bearer, PDN connectivity, and more
[OAI wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
[OAI softmodem build procedure](BUILD.md)
[Running the OAI softmodem ](RUNMODEM.md)

View File

@@ -1,6 +1,6 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
The Duranta OpenAirInterface software can be obtained Github. You will
The OpenAirInterface software can be obtained from our gitLab server. You will
need a git client to get the sources. The repository is used for main
developments.
@@ -13,9 +13,9 @@ sudo apt-get update
sudo apt-get install git
```
## Clone the Git repository (for OAI Users without login to github server)
## Clone the Git repository (for OAI Users without login to gitlab server)
The [openairinterface5g repository](https://github.com/duranta-project/openairinterface5g.git)
The [openairinterface5g repository](https://gitlab.eurecom.fr/oai/openairinterface5g.git)
holds the source code for the RAN (4G and 5G).
### All users, anonymous access
@@ -23,24 +23,37 @@ holds the source code for the RAN (4G and 5G).
Clone the RAN repository:
```shell
git clone https://github.com/duranta-project/openairinterface5g.git
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git
```
### For contributors
Configure git with your name/email address, important if you are developer and
want to contribute by pushing code. Please put your full name and the e-mail
address you use in Gitlab.
```shell
git config --global user.name "Your Name"
git config --global user.email "Your email address"
```
More information can be found in [the contributing page](../CONTRIBUTING.md).
## Which branch to checkout?
- `develop`: contains recent commits that are tested on our CI test bench. The
update frequency is about once a week. **This is the
update frequency is about once a week. 5G is only in this branch. **It is the
recommended and default branch.**
- `master`: contains a known stable version.
You can find the latest stable tag release [here](https://github.com/duranta-project/openairinterface5g/releases).
You can find the latest stable tag release [here](https://gitlab.eurecom.fr/oai/openairinterface5g/tags).
The tag naming conventions are:
- On `develop` branch **`YYYY.wXX`**
* `YYYY` is the calendar year
* `XX` the week number within the year
- On `develop` branch **`vX.Y`**
* a semantic version number
- On `master` branch: **v`x`.`y`.`z`**
- On `develop` branch **`yyyy`.w`xx`**
* `yyyy` is the calendar year
* `xx` the week number within the year
More information on work flow and policies can be found in [this
document](./code-style-contrib.md).

View File

@@ -35,14 +35,14 @@ Please try to use the same commit ID on both eNB/UE hosts.
```bash
$ ssh sudousername@machineB
git clone https://github.com/duranta-project/openairinterface5g.git enb_folder
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git enb_folder
cd enb_folder
git checkout develop
```
```bash
$ ssh sudousername@machineC
git clone https://github.com/duranta-project/openairinterface5g.git ue_folder
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ue_folder
cd ue_folder
git checkout develop
```
@@ -315,6 +315,8 @@ iperf -c 10.0.1.1 -u -t 30 -b 2M -i 1 -fm -B 10.0.1.2 -p 5002
----
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
[oai softmodem features](FEATURE_SET.md)
[oai softmodem build procedure](BUILD.md)

View File

@@ -40,14 +40,14 @@ Please try to use the same commit ID on both eNB/UE hosts.
```bash
$ ssh sudousername@machineB
git clone https://github.com/duranta-project/openairinterface5g.git enb_folder
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git enb_folder
cd enb_folder
git checkout develop
```
```bash
$ ssh sudousername@machineC
git clone https://github.com/duranta-project/openairinterface5g.git ue_folder
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ue_folder
cd ue_folder
git checkout develop
```
@@ -295,6 +295,8 @@ iperf operations can also be performed.
----
[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
[oai softmodem features](FEATURE_SET.md)
[oai softmodem build procedure](BUILD.md)

View File

@@ -182,12 +182,12 @@ Baseband devices using DPDK-compatible driver
## Building OAI with ORAN-AAL
OTA deployment is precisely described in the following tutorial:
- [NR_SA_Tutorial_COTS_UE](./NR_SA_Tutorial_COTS_UE.md)
- [NR_SA_Tutorial_COTS_UE](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/NR_SA_Tutorial_COTS_UE.md)
Instead of section *3.2 Build OAI gNB* from the tutorial, run the following commands:
```bash
# Get openairinterface5g source code
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g
git checkout develop

View File

@@ -77,7 +77,7 @@ sudo uhd_images_downloader
```bash
# Get openairinterface5g source code
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g
git checkout develop

View File

@@ -63,7 +63,7 @@ sudo uhd_images_downloader
```bash
# Get openairinterface5g source code
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g
git checkout develop

View File

@@ -44,8 +44,7 @@ PTP enabled switches and Grandmaster clock we have tested with:
|Fibrolan Falcon-RX/812/G|
|Qulsar Qg2 (Grandmaster)|
**S-Plane synchronization is mandatory.** S-plane support is done via
`ptp4l` and `phc2sys`. Make sure your version matches.
**S-Plane synchronization is mandatory.** S-plane support is done via `ptp4l` and `phc2sys`. Make sure your version matches.
| Software | Software Version|
|-----------|-----------------|
@@ -229,19 +228,19 @@ Once installed you can use this configuration file for ptp4l (`/etc/ptp4l.conf`)
```
[global]
domainNumber 24
clientOnly 1
slaveOnly 1
time_stamping hardware
tx_timestamp_timeout 50
tx_timestamp_timeout 1
logging_level 6
summary_interval 0
#priority1 127
[PTP_ENABLED_NIC_INTERFACE]
[your_PTP_ENABLED_NIC]
network_transport L2
hybrid_e2e 0
```
You need to increase `tx_timestamp_timeout` to 100 if needed. You will see that in the logs of ptp.
You need to increase `tx_timestamp_timeout` to 50 or 100 for Intel E-810. You will see that in the logs of ptp.
Create the configuration file for ptp4l (`/etc/sysconfig/ptp4l`)
@@ -252,7 +251,7 @@ OPTIONS="-f /etc/ptp4l.conf"
Create the configuration file for phc2sys (`/etc/sysconfig/phc2sys`)
```
OPTIONS="-s PTP_ENABLED_NIC_INTERFACE -w -n 24 -r -r -m -R 8"
OPTIONS="-a -r -r -n 24"
```
The service of ptp4l (`/usr/lib/systemd/system/ptp4l.service`) should be configured as below:
@@ -296,7 +295,8 @@ Beware that PTP issues may show up only when running OAI and XRAN. If you are us
1. Make sure that you have `skew_tick=1` in `/proc/cmdline`
2. For Intel E-810 cards set `tx_timestamp_timeout` to 50 or 100 if there are errors in ptp4l logs
3. Other time sources than PTP, such as NTP or chrony timesources, should be disabled. Make sure they are enabled as further below.
4. If `rms` or `delay` in `ptp4l` or `offset` in `phc2sys` logs remain high then you can try pinning the `ptp4l` and `phc2sys` processes to an isolated CPU.
4. Make sure you set `kthread_cpus=<cpu_list>` in `/proc/cmdline`.
5. If `rms` or `delay` in `ptp4l` or `offset` in `phc2sys` logs remain high then you can try pinning the `ptp4l` and `phc2sys` processes to an isolated CPU.
```bash
#to check there is NTP enabled or not
@@ -400,7 +400,7 @@ sudo ninja deinstall -C build
Clone OAI code base in a suitable repository, here we are cloning in `~/openairinterface5g` directory,
```bash
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g/
```
@@ -421,14 +421,14 @@ git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/
```bash
git clone https://github.com/openairinterface/o-du-phy.git ~/phy
cd ~/phy
git checkout 11.1.3 # the tag points to the `main` branch which has all patches applied that are relevant for OAI integration; the tag matches the value of cmake variable `K_VERSION`
git checkout <desired-tag> # shall match a variable `K_VERSION`
```
or use `xran_DOWNLOAD` option when compiling OAI gNB.
Compile the fronthaul interface library by calling `make` and the option
`XRAN_LIB_SO=1` to have it build a shared object. Note that we provide two
environment variables `RTE_SDK` for the path to the source tree of DPDK, and
`XRAN_DIR` to set the path to the fronthaul library.
`XRAN_DIR` to set the path to the fronthaul library. For building for a Arm
target, set as well the environment variable `TARGET=armv8`.
**Note**: you need at least gcc-11 and g++-11.
@@ -1258,7 +1258,7 @@ The OAI configuration file [`gnb.sa.band78.106prb.fhi72.1x1-proto-ru.conf`](../t
First, compile the RU as outlined in the [building ProtO-RU tutorial](https://github.com/NUS-CIR/ProtO-RU/tree/proto-ru?tab=readme-ov-file#building-proto-ru).
Then, ensure that both your DU and ProtO-RU host are PTP synchronized.
Next, use the RU config, [protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml](https://github.com/NUS-CIR/ProtO-RU/blob/proto-ru/proto-ru/conf-files/protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml), which corresponds to the above mentioned DU config file. Please note that the RU delay profile might need to be adjusted according to the setup. The E2E test with xran K release required `T2a_max_cp_ul: 2985`.
Next, use the RU config, [protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml](https://github.com/NUS-CIR/ProtO-RU/blob/proto-ru/proto-ru/conf-files/protoru-OAI-B210-TDD-n78-40MHz-1x1-30kHz.yml), which corresponds to the above mentioned DU config file.
In addition, please adapt the DU MAC address and VLAN tag to your needs.
ProtO-RU was successfully tested with USRP B210.
@@ -1556,10 +1556,7 @@ Edit the sample OAI gNB configuration file and check following parameters:
* `RUs` section
* Set an isolated core for RU thread `ru_thread_core`, in our environment we are using CPU 6
* If testing with a numerology different than 1 (e.g., FDD with numerology 0),
set `nr_scs_for_raster` to the used numerology, and adapt `sl_ahead`: it must be
strictly less than the number of slots in a frame (e.g., 5 for numerology 0).
* `fhi_72` (FrontHaul Interface) section: this config follows the structure
that is employed by the xRAN library (`xran_fh_init` and `xran_fh_config`
structs in the code):
@@ -2087,7 +2084,7 @@ Compiled libraries:
#### Using build_oai script
```bash
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g/cmake_targets/
./build_oai -I # if you never installed OAI, use this command once before the next line
./build_oai --install-optional-packages # for pcre/libpcre3, libssh, and libxml2 library installation
@@ -2098,7 +2095,7 @@ PKG_CONFIG_PATH=/opt/mplane-v2/lib/pkgconfig ./build_oai --gNB --ninja -t oran_f
#### Using cmake directly
```bash
git clone https://github.com/duranta-project/openairinterface5g.git ~/openairinterface5g
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g/
mkdir build && cd build
cmake .. -GNinja -DOAI_FHI72=ON -DOAI_FHI72_MPLANE=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib
@@ -3708,7 +3705,7 @@ sudo ./nr-softmodem -O <without-mplane-configuration file> --thread-pool <list o
## Contact in case of questions
You can ask your question on the [mailing lists](https://github.com/duranta-project/openairinterface5g/wiki/MailingList).
You can ask your question on the [mailing lists](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/MailingList).
Your email should contain below information:
@@ -3721,4 +3718,4 @@ Your email should contain below information:
- RU Vendor and Version.
- In case your question is related to performance, include a small description of the machine (CPU, RAM and networking card) and diagram of your testing environment.
- If you have any issues related to PTP or synchronization, then first check the section "Debugging PTP issues". Then share your problem with PTP version you are using, switch details and master clock.
- Known/open issues are present on [Github](https://github.com/duranta-project/openairinterface5g/issues), so keep checking.
- Known/open issues are present on [GitLab](https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues), so keep checking.

View File

@@ -133,9 +133,6 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
## Developer tools
- [code-style-contrib.md](./code-style-contrib.md): overall working practices, code style, and review process
- [git-guide.md](./git-guide.md): Git how-tos — commit signing setup, branch
management, submodules, recovering from mistakes, reusing conflict
resolutions (rerere)
- [cross-compile.md](./cross-compile.md): how to cross-compile OAI for ARM
- [clang-format.md](./clang-format.md): how to format the code. See also the
next entry for an error detection tool.

View File

@@ -632,23 +632,10 @@ The following flow documents the current OAI stack path for paging-triggered
service resumption in SA: context release to idle, NGAP/F1AP/PCCH paging, then
RRC setup with NAS Service Request.
End-to-end flow is split across these 3GPP procedures:
| Spec clause | Procedure name | Actor | Spec role in this flow |
|-------------|----------------|-------|------------------------|
| TS 23.502 §4.2.3.3 | Network Triggered Service Request | AMF / 5GC | Network must deliver MT signalling/data to a CM-IDLE UE. "The Paging Request triggers the UE Triggered Service Request procedure in the UE". Step 4b = Paging Request to RAN, step 6 = UE initiates §4.2.3.2 |
| TS 23.502 §4.2.3.2 | UE Triggered Service Request | UE | CM-IDLE UE may initiate SR "as a response to a network paging request" |
| TS 24.501 §5.6.2.2 | Paging for 5GS services | UE NAS | On paging indication from lower layers: initiate service request (§5.6.1.2) when in `5GMM-REGISTERED` and `5GMM-IDLE` |
| TS 24.501 §8.2.16 | SERVICE REQUEST | UE NAS | NAS PDU sent by UE |
#### OAI implementation
In summary:
- UE transitions to `RRC_IDLE` and AMF transitions UE to `CM-IDLE`
- CN-triggered paging is performed with `5G-S-TMSI` (NGAP Paging -> RRC Paging)
- One radio page per cell per NGAP PAGING at UE PO
- UE resumes via NAS Service Request and `RRCSetup`/`RRCSetupComplete`
- AMF continues §4.2.3.3 after Initial UE Message / context setup
```mermaid
sequenceDiagram
@@ -680,27 +667,21 @@ sequenceDiagram
cu->>cu: ngap_gNB_handle_paging()
cu->>cu: decode_ng_paging()
cu->>cu: rrc_gNB_process_PAGING_IND()
cu->>cu: rrc_send_paging_to_dus()
cu->>du: F1AP Paging
du->>du: DU_handle_Paging()
du->>du: f1_paging()
du->>du: nr_mac_pcch_enqueue()
Note over du: at UE PO: schedule_nr_pcch()
du->>du: do_NR_Paging()
du->>ue: RRC Paging (ng-5G-S-TMSI, P-RNTI)
du->>ue: RRC Paging (ng-5G-S-TMSI)
ue->>ue: nr_rrc_ue_decode_pcch()
ue->>ue: NAS_PAGING_IND
ue->>ue: generateServiceRequest()
ue->>ue: send_nas_initial_ul_transfer_req()
Note over ue: paging match triggers Service Request [24.501 §5.6.2]
Note over ue,cn: Resume service
ue->>ue: NAS_INITIAL_UL_TRANSFER_REQ
ue->>ue: nr_rrc_ue_prepare_RRCSetupRequest()
ue->>ue: nr_rrc_trigger_mac_ra(NR_MAC_RA_START_SETUP)
Note over ue,cn: Resume
ue->>du: RRCSetupRequest
du->>cu: F1AP Initial UL RRC Message Transfer (RRCSetupRequest)
ue->>ue: nr_rrc_ue_prepare_RRCSetupRequest()
cu->>cu: rrc_handle_RRCSetupRequest()
cu->>du: F1AP DL RRC Message Transfer (RRCSetup)
du->>ue: RRCSetup
@@ -727,8 +708,7 @@ In OAI RFsim lab runs, a practical trigger sequence is:
3. send host-side traffic to UE IP
Relevant specs:
- TS 23.502: §4.2.3.3 Network Triggered Service Request (AMF pages, step 4b),
UE Triggered Service Request §4.2.3.2 (by network paging)
- TS 23.502 §4.2.3.3: Network Triggered Service Request
- TS 24.501 §5.6.2.2: Paging for 5G services
- TS 24.501 §5.6.1: Service Request procedure
- TS 38.331 §5.3.2: Paging

View File

@@ -90,9 +90,9 @@ the [MAC configuration](../MAC/mac-usage.md) as well for SIB configuration.
`0xffffff` is a reserved value and means "no SD"
Note that: SST=1, no SD is "eMBB"; SST=2, no SD is "URLLC"; SST=3, no SD
is "mMTC"
- `enable_sdap` (default: true): set `sdap-HeaderUL` and `sdap-HeaderDL` to
present in the RRC `SDAP-Config` IE for SA PDU sessions. If false, both
headers are absent (per DRB). SDAP entities are still created, SDAP layer always enabled.
- `enable_sdap` (default: true): enable the use of the SDAP layer. If
deactivated, a transparent SDAP header is prepended to packets, but no
further processing is being done.
- `cu_sibs` (default: `[]`) list of SIBs to give to the DU for transmission.
Currently supported:
- SIB2: serving-cell reselection parameters (configured in `sib2_config`)

View File

@@ -263,7 +263,7 @@ Finally the number of TX physical antenna in the RU part of the configuration fi
It is possible to limit the number supported DL MIMO layers via RRC configuration, e.g. to a value lower than the number of logical antenna ports configured, by using the configuration file parameter `maxMIMO_layers`.
[Example of configuration file with parameters for 2-layer MIMO](../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf)
[Example of configuration file with parameters for 2-layer MIMO](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf)
## IF (Intermediate Frequency) equipment

View File

@@ -80,14 +80,10 @@
## Pipelines
### [RAN-GitHub-Container-Parent](https://jenkins-oai.eurecom.fr/job/RAN-GitHub-Container-Parent/)
### [RAN-Container-Parent](https://jenkins-oai.eurecom.fr/job/RAN-Container-Parent/)
**Purpose**: automatically triggered tests on pull request creation or push
https://github.com/duranta-project/openairinterface5g/labels/documentation
https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
**Purpose**: automatically triggered tests on MR creation or push, from Gitlab
Webhook ~documentation ~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
This pipeline has basically two main stages, as follows. For the image build,
please also refer to the [dedicated documentation](../docker/README.md) for
@@ -96,18 +92,12 @@ information on how the images are built.
#### Image Build pipelines
- [RAN-ARM-Cross-Compile-Builder](https://jenkins-oai.eurecom.fr/job/RAN-ARM-Cross-Compile-Builder/)
https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- orion: Cross-compilation from Intel to ARM
- base image from `Dockerfile.base.ubuntu.cross-arm64`
- build image from `Dockerfile.build.ubuntu.cross-arm64` (no target images)
- [RAN-RHEL-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL-Cluster-Image-Builder/)
https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
- [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- cluster (`Asterix-OC-oaicicd-session` resource): RHEL image build using the OpenShift Cluster (using gcc/clang)
- base image from `Dockerfile.build.rhel9`
- build image from `Dockerfile.build.rhel9`, followed by
@@ -122,13 +112,10 @@ information on how the images are built.
- build image from `Dockerfile.phySim.rhel9` (creates as direct target physical simulator
image)
- build image from `Dockerfile.clang.rhel9` (compilation only, artifacts not used currently)
- [RAN-Ubuntu-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-Image-Builder/)
https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
- [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- run formatting check from `ci-scripts/docker/Dockerfile.formatting.ubuntu`
- obelix: Ubuntu image build using docker
- obelix: Ubuntu image build using docker (Note: builds Ubuntu images of newer version while pipeline is named U18!)
- base image from `Dockerfile.base.ubuntu`
- build image from `Dockerfile.build.ubuntu`, followed by
- target image from `Dockerfile.eNB.ubuntu`
@@ -142,10 +129,7 @@ information on how the images are built.
- target image from `Dockerfile.gNB.fhi72.ubuntu`
- build unit tests from `ci-scripts/docker/Dockerfile.unittest.ubuntu`, and run them
- [RAN-Ubuntu-ARM-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-ARM-Image-Builder/)
https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~BUILD-ONLY ~4G-LTE ~5G-NR
- gracehopper3-oai: ARM Ubuntu image build using docker
- base image from `Dockerfile.base.ubuntu`
- build image from `Dockerfile.build.ubuntu`, followed by
@@ -154,10 +138,7 @@ information on how the images are built.
- target image from `Dockerfile.nrUE.ubuntu`
- target image from `Dockerfile.gNB.aerial.ubuntu`
- [RAN-Ubuntu-Jetson-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-Jetson-Image-Builder/)
https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~BUILD-ONLY ~4G-LTE ~5G-NR
- jetson3-oai: ARMv8 Ubuntu image build using docker
- base image from `Dockerfile.base.ubuntu`
- build image from `Dockerfile.build.ubuntu`, followed by
@@ -168,113 +149,113 @@ information on how the images are built.
#### Image Test pipelines
- [OAI-CN5G-COTS-UE-Test](https://jenkins-oai.eurecom.fr/job/OAI-CN5G-COTS-UE-Test/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- using 5GC bench (resources `Cetautomatix`, `Dogmatix`): Attach/Detach of UE with multiple PDU sessions
- [OAI-FLEXRIC-RAN-Integration-Test](https://jenkins-oai.eurecom.fr/job/OAI-FLEXRIC-RAN-Integration-Test/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
- [OAI-FLEXRIC-RAN-Integration-Test](https://jenkins-oai.eurecom.fr/job/OAI-FLEXRIC-RAN-Integration-Test/) ~5G-NR ~nrUE
- selfix (gNB, nrUE, OAI 5GC, FlexRIC)
- uses RFsimulator, tests FlexRIC/E2 interface and xApps
- [RAN-gNB-N300-Timing-Phytest-LDPC](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-gNB-N300-Timing-Phytest-LDPC/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- caracal + N310
- pure performance test through phy-test scheduler, see command line for more details
- [RAN-L2-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-L2-Sim-Test-4G/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- obelix (eNB, 1x UE, OAI EPC)
- L2simulator: skips physical layer and uses proxy between eNB and UE
- [RAN-LTE-FDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-LTEBOX-Container/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- hutch + B210, nano w/ ltebox + 2x UE
- tests RRC inactivity timers, different bandwidths, IF4p5 fronthaul
- [RAN-LTE-FDD-OAIUE-OAICN4G-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-FDD-OAIUE-OAICN4G-Container/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- hutch + B210 (eNB), carabe + B210 (4G UE), nano w/ OAI 4GC
- tests OAI 4G for 10 MHz/TM1; known to be unstable
- [RAN-LTE-TDD-2x2-Container](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-LTE-TDD-2x2-Container/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- obelix + N310, porcepix, up2 + Quectel
- TM1 and TM2 test, IF4p5 fronthaul
- [RAN-LTE-TDD-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-LTE-TDD-LTEBOX-Container/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- starsky + B210, nano w/ ltebox + 2x UE
- TM1 over bandwidths 5, 10, 20 MHz in Band 40, default scheduler for 20 MHz
- [RAN-NSA-B200-Module-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-NSA-B200-Module-LTEBOX-Container/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~4G-LTE ~5G-NR
- nepes + B200 (eNB), ofqot + B200 (gNB), idefix + Quectel, nepes w/ ltebox
- basic NSA test
- [RAN-PhySim-Cluster-4G](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster-4G/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- tests 4G physical simulators (`nr_dlsim`, etc.) in OpenShift Cluster (x86)
- see [`./physical-simulators.md`](./physical-simulators.md) for an overview
- [RAN-PhySim-Cluster-5G](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster-5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~5G-NR ~nrUE
- tests 5G physical simulators (`nr_dlsim`, etc.) in OpenShift Cluster (x86)
- see [`./physical-simulators.md`](./physical-simulators.md) for an overview
- [RAN-PhySim-GraceHopper-5G](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-GraceHopper-5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~5G-NR ~nrUE
- tests 5G physical simulators (`nr_dlsim`, etc.) on Nvidia GraceHopper (ARMv9)
- see [`./physical-simulators.md`](./physical-simulators.md) for an overview
- [RAN-RF-Sim-Test-4G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-4G/)
https://github.com/duranta-project/openairinterface5g/labels/4G-LTE
~4G-LTE
- acamas (eNB, lteUE, OAI EPC)
- uses RFsimulator, for FDD 5, 10, 20MHz with core, 5MHz noS1
- [RAN-RF-Sim-Test-5G](https://jenkins-oai.eurecom.fr/job/RAN-RF-Sim-Test-5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~5G-NR ~nrUE
- acamas (gNB, nrUE, OAI 5GC)
- uses RFsimulator, TDD 40MHz, FDD 40MHz, F1 split
- [RAN-SA-AW2S-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AW2S-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- 5G-NR SA test setup: avra + AW2S, amariue, OAI CN5G
- uses OpenShift cluster for CN deployment and container images for gNB deployment
- multi UE testing using Amarisoft UE simulator
- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- ofqot + B200, idefix + Quectel, nepes w/ sabox
- basic SA test (20 MHz TDD), F1, reestablishment, ...
- [RAN-SA-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-OAIUE-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~5G-NR ~nrUE
- 5G-NR SA test setup: gNB on avra + N310, OAIUE on caracal + N310, OAI CN5G
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
- [RAN-SA-AERIAL-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on gracehopper1-oai + Foxconn RU, up2 + COTS UE (Quectel RM520N), OAI CN5G
- container images for gNB deployment
- [RAN-SA-Multi-Antenna-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Multi-Antenna-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- matix + N310 (gNB), up2 + COTS UE (Quectel RM520N), OAI 5GC deployed in docker on matix
- NR performance tests: 2x2 configuration, 60 MHz and 100 MHz bandwidth
- [RAN-SA-FHI72-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-FHI72-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- cacofonix + FHI72 + Metanoia (gNB), up2 (Quectel RM520N UE), OAI CN5G
- OpenShift cluster for CN deployment
- FHI 7.2 testing with 100 MHz bandwidth, 2 layers in DL
- [RAN-SA-Handover-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-Handover-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- groot (CU+DU0) + B210, rocket (DU1) + B210, raspix (Quectel RM520N UE), OAI CN5G
- OpenShift cluster for CN deployment
- Attenuator (mini circuits RC4DAT-6G-60) - controlled from rocket
- [RAN-Channel-Simulation](https://jenkins-oai.eurecom.fr/job/RAN-Channel-Simulation/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- gracehopper1-oai
- run channel simulation on CPU and GPU using test_channel_scalability
- [RAN-SA-AERIAL-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-OAIUE-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
https://github.com/duranta-project/openairinterface5g/labels/nrUE
~5G-NR ~nrUE
- 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on gracehopper1-oai + WNC RU, OAIUE on jetson1-oai + B210, OAI CN5G
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
- [RAN-SA-FHI72-MPLANE-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-FHI72-MPLANE-CN5G/)
https://github.com/duranta-project/openairinterface5g/labels/5G-NR
~5G-NR
- cacofonix + FHI72 + Benetel550 (gNB), AmarisoftUE, OAI CN5G
- OpenShift cluster for CN deployment
- FHI 7.2 testing with 40 MHz, 4x4 MIMO configuration and 100 MHz, 2x2 MIMO configuration
- FHI 7.2 Configuration and Performance Management via NETCONF session of an O-RU
### RAN-CI-NSA-Trigger
***DEFUNCT***: longer-running over-the-air LTE, NSA, and SA tests. To be integrated into RAN-Container-Parent.
- [RAN-NSA-2x2-Module-OAIEPC](https://jenkins-oai.eurecom.fr/job/RAN-NSA-2x2-Module-OAIEPC/)
- obelix + N310 (eNB), asterix + N310 (gNB), nrmodule2 + Quectel, porcepix w/ Magma EPC
- LTE 2x2 and NR 2x2 (non-standalone)
## How to reproduce CI results
The CI builds docker images at the beginning of every test run. To see the

View File

@@ -42,7 +42,7 @@ Our code might not work with all 5G phones yet, but we are constantly improving
## Repository
[OAI](https://github.com/duranta-project/openairinterface5g)
[OAI](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop)
## Architecture Setup
@@ -58,7 +58,7 @@ The photo depicts the FR1 setup part of the scheme above:
## Build and Install
General guidelines to build eNB and gNB :
See [Building UE, eNB and gNb executables](./BUILD.md)
See [Building UE, eNB and gNb executables](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/doc/BUILD.md#building-ues-enodeb-and-gnodeb-executables)
- **eNB**

View File

@@ -10,24 +10,23 @@ review is performed.
## General
Duranta OpenAirInterface employs both human review and automated CI tests to
judge whether a code contribution is ready to be merged.
OpenAirInterface employs both human review and automated CI tests to judge
whether a code contribution is ready to be merged.
The contributor has to sign a contributor license agreement (CLA) as described
in [`CONTRIBUTING.md`](../CONTRIBUTING.md). After creating an account on
Github, the contributor can open a pull request from a fork: he becomes the
"author" of such code contribution. A senior Duranta OAI member will review
this work, and make suggestions for possible improvements. Each week, we
discuss the progress of the pull requests in a [weekly developer
call](https://github.com/duranta-project/openairinterface5g/wiki/Developer-Meetings),
and discuss which pull requests can be merged.
in [`CONTRIBUTING.md`](../CONTRIBUTING.md). After creating an account on the
Eurecom Gitlab, the contributor can open a merge request: he becomes the
"author" of such code contribution. A senior OAI member will review this work,
and make suggestions for possible improvements. Each week, we discuss the
progress of the merge requests in a [weekly external developer
call](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/OpenAirDevMeetings),
and discuss which merge requests can be merged.
The CI consists in various Jenkins pipelines that run on each pull request.
The CI consists in various Jenkins pipelines that run on each merge request.
See [`TESTBenches.md`](./TESTBenches.md) for more details about the CI setup.
There is the official [Github Help](https://docs.github.com/) that can help you
with any questions regarding Github. Note that unlike Gitlab, password-based
code pushes are not allowed. Also, we recommend reading the [Git
There is the official [Gitlab Help](https://docs.gitlab.com/) that can help you
with any questions regarding Gitlab. We recommend reading the [Git
Book](https://git-scm.com/book/en/v2) to use Git properly.
## Basic coding rules
@@ -58,11 +57,8 @@ A number of high-level comments:
put output variables (via a pointer) last
- Do not do premature optimization; measure the code before writing SIMD
instructions by hand, and measure again to show it is faster.
- Avoid variables marked with `extern`. Function prototypes must be in one
unique header file that should be included by all source files that define
this function or use it.
If in doubt, check out code that has been recently written (e.g., use the pull
If in doubt, check out code that has been recently written (e.g., use the merge
requests page to check for code that has recently been added) and follow that
style. Checking surrounding code is usually not the best idea, as OAI has a
long history in which coding rules were not really enforced.
@@ -78,8 +74,15 @@ that might be useful; if this document and `.clang-format` contradict,
You should be familiar with git branching, merging, and rebasing.
To make branches simple to read for a reviewer, developer, or anyone interested
in the code, please keep your branch history linear (i.e., no merges). Each commit should be able to
The target branch for every contribution, and the general development branch,
is `develop`. Typically every week, we collect multiple merge requests in an
"integration branch" that gets tested by the CI individually. If everything is
fine, we merge to develop and tag it `YYYY.wXX` with `YYYY` the current year,
and `XX` the week number.
Note that the above includes a lot of merging, making the Git history difficult
to understand. To not needlessly increase the complexity, please keep your
branch history linear (i.e., no merges). Each commit should be able to
compile, and ideally be able to run an End-to-End test of gNB/UE using RFsim.
This can be achieved by making each commit a **logical change** to be applied to
the code base, which also facilitates the review of your changes. The Linux
@@ -105,118 +108,70 @@ A commit message can (and often should) take several lines. One-line commit
messages should be reserved for very simple changes. If in doubt, prefer to
explain your work more than less.
### Release Strategy
The workflow of the integration branch has its weaknesses; we might revise this
in the future towards a workflow using rebase to integrate work of different
people, in order to simplify the history, and allow the usage of tools such as
`git bisect` to search for bugs.
The target branch for every contribution, and the general development branch,
is `develop`. Typically every week, we collect multiple pull requests in an
"integration branch" that gets tested by the CI individually. If everything is
fine, we merge to develop and tag it `YYYY.wXX` with `YYYY` the current year,
and `XX` the week number.
After some time, we make a stable release using a semantic version number,
e.g., `v3.0`. We target to make releases bi-yearly.
After some time, we make a stable release. For this, we simply merge develop
into master, and give a semantic versioning number, e.g., `v1.1`. We target to
make releases bi-yearly.
### How to manage your own branch
Branch off the latest `develop` branch before starting to work, keep your
branch synchronized with `origin/develop` through regular rebases, and push
with `--force-with-lease` after rebasing. The step-by-step commands — including
how to rebase over multiple develop tags in intermediate steps and how to avoid
resolving the same conflicts repeatedly with `git rerere` — are in the
[branch management section of the Git guide](./git-guide.md#managing-your-own-branch).
### Use of git commit trailers
As noted in the [contribution guidelines](../CONTRIBUTING.md), you have to sign
all your commits. Thus, every commit must have a git commit trailer that reads
```
Signed-off-by: Full Name <email-for-cla>
Before starting to work, please make sure to branch off the latest `develop`
branch. Make commits as appropriate.
```bash
$ git fetch origin
$ git checkout develop
$ git checkout -b my-new-feature # name as appropriate
$ git add -p # add changes for change set 1, use `-p` to review what to include
$ git commit # in the editor, describe your changes
$ git add -p # add changes for change set 2
$ git commit # in the editor, describe your changes
```
There are additional commit trailers that you can or should use:
Again, commit message should take multiple lines; after the initial title, a
blank line should follow. Read the `DISCUSSION` section in `man git commit` for
more information.
- `Assisted-by: <Name>:<model>`: if you have been assisted by an AI/LLM, you
must disclose this by indicating both the LLM name and model. Note that LLMs
do not author, as _the submission is under your name_ (i.e., NEVER add an LLM
through `Co-authored:by:`). The [Linux kernel documentation on AI
assistents](https://docs.kernel.org/process/coding-assistants.html)
might be helpful.
- `Reviewed-by: Full Name <email>` for a person that reviewed a code. We attach
this trailer to the merge commit for people that reviewed a pull request.
- `Co-authored-by: Full Name <email>` for a person that significantly
contributed to a commit and has co-authorship.
- `Fixes: <commit> ("<title>")` if a given commit fixes bug in an earlier,
referenced commit. For ease-of-use, please include the commit title, and only
the commit SHA, not a link.
- `Closes: #Issue` if a specific commit closes a bug. If the pull request
description includes this, we add this to the merge commit.
- `Reported-by: Full Name <email>` if a person reported a bug or other useful
information that led to this commit.
- `Tested-By: Full Name <email>` if a person tested a given patch.
This list is non-exhaustive, and you might attach more trailers. Please also
check the documentation via `man git-interpret-trailers`, and note that the
general free-form format is (from the documentation):
```
key: value
This means that the trimmed <key> and <value> will be separated by ": " (one colon followed by one space).
If your development takes longer, make sure to synchronize regularly with
`origin/develop` using `git rebase`:
```bash
$ git fetch origin
$ git rebase -i origin/develop
```
### AI Assistants
If you do logical changes, you should not have to resolve the same conflicts
over and over again. Note that if you jumped over multiple develop tags, you
can also rebase in intermediate steps, in case you fear the differences might
be too big.
```
$ git rebase -i 2023.w38
$ git rebase -i 2023.w41
$ git rebase -i develop
```
These guidelines are mostly based on [linux kernel
guidelines](https://docs.kernel.org/process/coding-assistants.html)
Once you rebased, push the changes to the remote
```
$ git push origin my-new-feature --force-with-lease # force with lease let's you only overwrite what you also have locally in origin/my-new-feature
```
This document provides guidance for AI tools and developers using AI assistance
when contributing to the respository.
## Merge Requests
AI tools helping with openairinterface development should follow the standard
openairinterface developement procedure. They should comply with Duranta OAIs
licensing requirements:
- All code must be compatible with CSSL v1.0
- Use appropriate SPDX license identifiers
AI agents MUST NOT add `Signed-off-by` nor `Co-authored-by` tags. Only humans
can legally certify the Developer Certificate of Origin (DCO). The human
submitter is responsible for:
- Reviewing all AI-generated code
- Ensuring compliance with licensing requirements
- Adding their own Signed-off-by tag to certify the DCO
- Taking full responsibility for the contribution
When AI tools contribute to openairinterface,
proper commit message helps track the evolving role of AI in the development process.
Contributions should include an `Assisted-by` tag in the following format:
Assisted-by: AGENT_NAME:MODEL_VERSION
- `AGENT_NAME` is the name of the AI tool or framework
- `MODEL_VERSION` is the specific model version used
Example:
Assisted-by: Claude:claude-3-opus
## Pull Requests
A pull request (PR) can be submitted as soon as the code is considered stable
A merge request (MR) can be submitted as soon as the code is considered stable
and reviewable. The idea is to start the review early enough so that the code
author (the PR owner) can incorporate fixes while the reviewer is giving
feedback. Note that while it should not be common, a refusal of a pull request
is a valid outcome of a pull request review (subject to proper justification).
author (the MR owner) can incorporate fixes while the reviewer is giving
feedback. Note that while it should not be common, a refusal of a merge request
is a valid outcome of a merge request review (subject to proper justification).
When preparing a contribution that is large, the developer is responsible for
warning the maintainers team, so that the review work can start as early as possible
warning the OAI team, so that the review work can start as early as possible
and run in parallel to the contribution finalization. Failing to do so, there
is a risk that the work will take a long time to be merged or might even not be
merged at all if judged too complex by the maintainers team. Also, note that big
merged at all if judged too complex by the OAI team. Also, note that big
contributions should be cut into small commits each containing a logical
change, as described above. Finally, as a rule of thumb, the smaller the pull
change, as described above. Finally, as a rule of thumb, the smaller the merge
request, the easier it will be to review and merge.
The reviewer comments on code changes ("open comments") that should be
@@ -225,55 +180,50 @@ resolved by themselves to double check the modifications and close such
comments. As an author, please don't resolve open comments (don't click the
"Resolve thread" button) unless explicitly instructed by the reviewer.
Note that the _pull request author_ asks for inclusion of code, so _they
Note that the _merge request author_ asks for inclusion of code, so _they
should make the review easy_; in particular, if facilitating review incurs
extra work to make a simpler code review (e.g., rewriting entire commits or
their order), this extra work is justified. This particularly(!) applies for
big pull requests.
big merge requests.
When opening a pull requests, the author should select `develop` as the target
branch, and add at least one of these labels when opening the pull request:
When opening a merge requests, the author should select `develop` as the target
branch, and add at least one of these labels when opening the merge request:
- https://github.com/duranta-project/openairinterface5g/labels/documentation:
don't perform any testing stages, for documentation
- https://github.com/duranta-project/openairinterface5g/labels/BUILD-ONLY:
execute only build stages, for code improvements without impact on 4G or 5G
code
- https://github.com/duranta-project/openairinterface5g/labels/4G-LTE: perform
4G tests
- https://github.com/duranta-project/openairinterface5g/labels/5G-NR: perform
5G tests
- https://github.com/duranta-project/openairinterface5g/labels/nrUE: perform
only 5G-UE related tests including physims
- ~documentation: don't perform any testing stages, for documentation
- ~BUILD-ONLY: execute only build stages, for code improvements without impact
on 4G or 5G code
- ~4G-LTE: perform 4G tests
- ~5G-NR: perform 5G tests
Failure to add a label will prevent the CI from running. If in doubt about the
right label, add both 4G and 5G labels. The CI posts the results in the
comments section of the pull request. Both pull request authors and reviewers
are responsible for manual inspection and pre-filtering of the CI results. An
overview of the CI tests is in [`TESTBenches.md`](./TESTBenches.md).
Failure to add a label will prevent the CI from running. You can add both
~4G-LTE and ~5G-NR together; if in doubt about the right label, add both. The
CI posts the results in the comments section of the merge request. Both merge
request authors and reviewers are responsible for manual inspection and
pre-filtering of the CI results. An overview of the CI tests is in
[`TESTBenches.md`](./TESTBenches.md).
To communicate the review progress both between author and reviewer, as well as
to the outside world, we (ab-)use the milestones feature of Github to track the
current progress. The milestone can be set when opening the pull request, and
to the outside world, we (ab-)use the milestones feature of Gitlab to track the
current progress. The milestone can be set when opening the merge request, and
during its lifetime in the sidebar on the right. Following options:
- _no milestone_: not ready for review yet and is generally used to wait for a
first CI run that the author will inspect and fix problems detected by the CI
(please limit the time in which your code is in that phase)
- [REVIEW_CAN_START](https://github.com/duranta-project/openairinterface5g/milestone/2): the reviewer can start the review
- [REVIEW_IN_PROGRESS](https://github.com/duranta-project/openairinterface5g/milestone/4): the reviewer is currently doing review, and might
- %REVIEW_CAN_START: the reviewer can start the review
- %REVIEW_IN_PROGRESS: the reviewer is currently doing review, and might
request changes to the code that the author should include (or refute with
justification)
- [REVIEW_COMPLETED_AND_APPROVED](https://github.com/duranta-project/openairinterface5g/milestone/3): the reviewer is happy with code changes
- %REVIEW_COMPLETED_AND_APPROVED: the reviewer is happy with code changes
(*open comments still have to be addressed!*)
- [OK_TO_BE_MERGED](https://github.com/duranta-project/openairinterface5g/milestone/1): the maintainers team plans to merge this; *do not push any changes
- %OK_TO_BE_MERGED: the OAI team plans to merge this; *do not push any changes
anymore at this point*.
## Review Form
The following is a check list that might be used by a reviewer to check that
code contribution fulfils minimum standard w.r.t. formatting, data types,
assertions, etc. The reviewer might copy/paste this form into a pull request,
assertions, etc. The reviewer might copy/paste this form into a merge request,
or simply check that all have been filled.
All points should be marked to complete a review.
@@ -302,9 +252,9 @@ Additional optional questions in case they apply:
Please report only true bugs in the [issue tracker](../../issues). Do not
report general user problems; use the [mailing
lists](https://github.com/duranta-project/openairinterface5g/wiki/MailingList)
lists](https://gitlab.eurecom.fr/oai/openairinterface5g/-/wikis/MailingList)
instead. If in doubt, prefer the mailing lists and if needed and requested by
the maintainers team, an issue will be opened.
the OAI team, an issue will be opened.
When reporting a bug, please clearly
- explain the problem,
@@ -315,4 +265,4 @@ When reporting a bug, please clearly
You are encouraged to use these bullet points to structure your issue for easy
understanding. Use code tags (the "insert code" button with symbol &lt;/&gt; in
the github editor) for logs and small code snippets.
the gitlab editor) for logs and small code snippets.

View File

@@ -61,7 +61,7 @@ Correct (Markdown):
**Bold text**
*Italic text*
![some image](./path/to/image.png)
![OAI Logo](./images/oai_final_logo.png) instead of <img src="./images/oai_final_logo.png" alt="OAI Logo">
| Feature | Description |
|---------------|---------------------------------|
@@ -75,7 +75,7 @@ Incorrect (HTML):
<b>Bold text</b>
<i>Italic text</i>
<img src="./path/to/image.png" alt="some image">
<img src="./images/oai_final_logo.png" alt="OAI Logo">
<table style="border-collapse: collapse; border: none;">
<tr>
@@ -114,7 +114,7 @@ Incorrect (HTML):
is](https://www.kernel.org/doc/html/latest/process/submitting-patches.html#separate-your-changes).
- See [OAI CN5G configuration files](#22-oai-cn5g-configuration-files) for
details.
- ![some image](./path/to/image.png)
- ![OAI Logo](./images/oai_final_logo.png)
```
## Inline code for technical elements

View File

@@ -1,390 +0,0 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
# Git guide
This guide collects the practical Git knowledge needed to contribute to OAI in
one place: how to set up commit signing, how to manage and synchronize a
feature branch, how to handle submodules, how to recover from common mistakes,
and how to avoid resolving the same merge conflicts over and over. It is a
how-to companion to the contribution *requirements*, which are
defined in [CONTRIBUTING.md](../CONTRIBUTING.md) (CLA, DCO, verified commits)
and [code-style-contrib.md](./code-style-contrib.md) (workflow, commit, and
review policy).
[[_TOC_]]
## Setting up commit signing
Every commit in a pull request must pass two independent CI checks, described
in [CONTRIBUTING.md](../CONTRIBUTING.md#commit-guidelines):
1. **[Developer Certificate of Origin (DCO)](https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin)**:
the commit message carries a `Signed-off-by:` trailer.
2. **[Verified commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)**:
the commit is cryptographically signed with an SSH or GPG key.
These are two different mechanisms: the sign-off is a line of text you add with
`git commit -s`, the signature is created automatically by Git once signing is
configured. You need both.
### Quick setup (SSH signing)
```bash
# 1. Generate a key pair (skip if you already have one)
ssh-keygen -t ed25519 -C "<your email>"
# 2. Configure Git to sign every commit with it
git config --global user.name "<Your Name>"
git config --global user.email "<your email>"
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
```
> **NOTE:**
> `--global` writes to `~/.gitconfig` and applies to every repository on the
> machine. When working on a shared server (or with different identities in
> different clones), drop `--global` to store the same settings in the current
> repository's `.git/config` only.
Then print the public key with `cat ~/.ssh/id_ed25519.pub` and paste it into
your GitHub account under *Settings → SSH and GPG keys → New SSH key*, choosing
the key type **Signing Key**.
> **NOTE:**
> Adding an SSH key for repository access does not automatically enable commit
> signing. The key must also be added under GitHub's Signing Keys settings.
For commits to show as *Verified* on GitHub:
- your `git config user.email` must match an email of your GitHub account,
- that email must be [verified in your GitHub account](https://docs.github.com/en/account-and-profile/how-tos/email-preferences/verifying-your-email-address),
- and it must be the email address used for the CLA (see
[CONTRIBUTING.md](../CONTRIBUTING.md)).
If you prefer GPG over SSH, set `gpg.format` to `openpgp` and `user.signingkey`
to your GPG key ID instead; see the [GitHub documentation on signing
commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)
for the full walkthrough of both methods.
### Signing off your commits (DCO)
The `Signed-off-by:` trailer is added with the `-s`/`--signoff` flag:
```bash
git commit -s # new commit
git commit --amend -s --no-edit # add the trailer to the last commit
```
It must read `Signed-off-by: Full Name <email-for-cla>`. See the
[commit trailers section](./code-style-contrib.md#use-of-git-commit-trailers)
of the contribution guidelines for this and other trailers.
### Verifying signed commits
You can verify that commits are properly signed locally using:
```bash
git log --show-signature
```
GitHub should also display a *Verified* badge next to signed commits once the
signing key has been correctly configured in your account.
For SSH commit signing, local Git verification may require an
`allowed_signers` file. This is only used for local verification in Git and is
not required by GitHub. If you see errors such as:
```text
No principal matched
Can't check signature
error: gpg.ssh.allowedSignersFile needs to be configured
```
create the file, add your signing identity, and enable it in your Git config:
```bash
mkdir -p ~/.config/git
echo "user@example.com ssh-ed25519 AAAACexamplekeystringhere" > ~/.config/git/allowed_signers
git config gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
```
> **NOTE:**
> This is only for local Git signature verification and does not affect GitHub,
> or remote repository behavior.
## Managing your own branch
The general development branch, and the target of every contribution, is
`develop`; see [GET_SOURCES.md](./GET_SOURCES.md) for the branch and tag model
(weekly `YYYY.wXX` tags, `vX.Y` releases). The rules for what a branch should
look like — linear history, small self-contained logical commits, commit
messages that explain *why* — are policy and live in
[code-style-contrib.md](./code-style-contrib.md#workflow).
Before starting to work, please make sure to branch off the latest `develop`
branch. Make commits as appropriate.
```bash
git fetch origin
git checkout develop
git checkout -b my-new-feature # name as appropriate
git add -p # add changes for change set 1, use `-p` to review what to include
git commit -s # in the editor, describe your changes
git add -p # add changes for change set 2
git commit -s # in the editor, describe your changes
```
Recent Git versions also offer `git switch` as a clearer alternative to
`git checkout` for branch operations: `git switch develop` changes branch,
`git switch -c my-new-feature` creates one.
Commit messages should take multiple lines; after the initial title, a blank
line should follow. Read the `DISCUSSION` section in `man git commit` for more
information. For documentation-only commits, prefix the title with `docs:`
(see [doc_best_practices.md](./doc_best_practices.md)).
Code must be formatted with clang-format; an optional pre-commit hook can
check this automatically at every commit — see
[clang-format.md](./clang-format.md) for its installation and how to combine
it with `git add -p`/`git stash -p`.
If your development takes longer, make sure to synchronize regularly with
`origin/develop` using `git rebase`:
```bash
git fetch origin
git rebase -i origin/develop
```
If you do logical changes, you should not have to resolve the same conflicts
over and over again. If the same conflicts do keep reappearing, e.g., when
maintaining a long-lived fork, consider enabling
[`git rerere`](#reusing-conflict-resolutions-with-git-rerere). Note that if
you jumped over multiple develop tags, you can also rebase in intermediate
steps, in case you fear the differences might be too big.
```bash
git rebase -i 2023.w38
git rebase -i 2023.w41
git rebase -i develop
```
Once you rebased, push the changes to the remote:
```bash
git push origin my-new-feature --force-with-lease # force with lease lets you only overwrite what you also have locally in origin/my-new-feature
```
### Fixing up earlier commits
The [workflow policy](./code-style-contrib.md#workflow) asks for a history
without "clean up" commits: when review or testing reveals a problem in an
earlier commit of your branch, fold the fix into that commit instead of
appending a `Fix bug` commit on top. Git automates this with fixup commits and
`--autosquash`:
```bash
git add -p # stage the fix
git commit --fixup=<commit> # creates a commit titled "fixup! <original title>"
git rebase -i --autosquash origin/develop # moves it after <commit> and squashes the two
```
During the `--autosquash` rebase, Git pre-arranges the todo list so each
`fixup!` commit is squashed into the commit it references; you normally just
accept it. The result is the same clean history as if the fix had been part of
the original commit.
A handy variant is `git commit --fixup=amend:<commit>`, which folds in the fix
and also rewrites the commit message: during the `--autosquash` rebase the
editor opens pre-filled with the original message, ready to be edited into the
new one.
## Working with submodules
Parts of the tree are Git submodules. After cloning, and after every branch
switch or pull, make sure they match the superproject:
```bash
git submodule update --init --recursive
```
A recurring review problem is the *unintended submodule pointer update*: a
submodule whose checked-out commit differs from what the superproject records
shows up in `git status` as `modified: <path> (new commits)`, and a broad
`git add .`, `git add -A`, or `git commit -a` silently records the new pointer
in your commit. To avoid it:
- review `git status` before committing and stage files explicitly (e.g. with
`git add -p`) rather than adding everything;
- if a pointer change was staged by accident, unstage it with
`git restore --staged <path>` and realign the submodule with
`git submodule update --init <path>`.
Only commit a submodule pointer change when updating that submodule is the
purpose of the commit, and say so in the commit message.
## Recovering from mistakes
To unstage a file that was added by accident (the changes stay in your working
tree), or to throw away local changes to a file:
```bash
git restore --staged <file> # unstage; keeps the modifications
git restore <file> # discard unstaged modifications - cannot be undone
```
`git reset` moves the current branch to another commit and differs in what it
does to your files:
```bash
git reset --soft HEAD~1 # undo the last commit, keep its changes staged (e.g. to re-split it)
git reset --hard <commit> # make branch, index and working tree identical to <commit>
```
> **Warning:** `git reset --hard` discards all uncommitted changes; there is no
> way to recover them.
Committed work is much harder to lose than it seems: `git reflog` records every
position of `HEAD` (commits, rebases, resets, checkouts) for a retention period
of at least 30 days, even for commits no branch points to anymore. If a rebase
or reset went wrong, find the last good state and reset back to it:
```bash
git reflog # e.g.: e75076172 HEAD@{5}: commit: doc: add git rerere guide
git reset --hard 'HEAD@{5}' # return the branch to that state
```
## Reusing conflict resolutions with git rerere
The `develop` branch is updated roughly once a week. Feature branches that live
for more than a few days therefore have to be re-synced with `develop`
repeatedly, and the same merge conflicts tend to reappear at every sync - often
in the same scheduler, PHY, or RRC files that several contributors touch at
once. Resolving the identical conflict by hand every week is error-prone and
wastes time.
Git ships a built-in feature for exactly this situation: `rerere`, short for
**reuse recorded resolution**. Once enabled, Git remembers how you resolved a
given conflict and replays that resolution automatically the next time the same
conflict appears.
This section explains how to enable and use it. It is a local developer
convenience: nothing about it changes the repository, the history you push, or
the contribution workflow.
### What it does
When a conflict occurs, `rerere` records the conflicted hunk (the *preimage*).
After you resolve it, `rerere` records your resolution (the *postimage*), keyed
by a hash of the preimage. The next time a conflict with the same preimage shows
up - in a later rebase, a later merge, or even another branch - Git reapplies
your recorded resolution instead of presenting the conflict again.
The data lives in `.git/rr-cache/` inside your local clone. It is never part of
any commit and is never pushed.
### Enabling it
Enable it once, globally, so it applies to every repository on your machine:
```bash
git config --global rerere.enabled true
git config --global rerere.autoupdate true
```
`rerere.autoupdate` stages a replayed resolution automatically. Without it, the
resolution is still written into your working tree, but you have to `git add`
the file yourself.
### Typical flow
The first time you hit a conflict after enabling `rerere`, resolve it exactly as
you always have:
```bash
# during a rebase or a merge that conflicts
git status # rerere reports which paths it is recording
# edit the conflicted files, remove the markers
git add <resolved-files>
git rebase --continue # or: git commit, for a merge
```
That resolution is now recorded. The next time the same conflict appears, Git
resolves it for you. With `autoupdate` on, the file is already staged and you can
go straight to:
```bash
git rebase --continue # or git commit
```
Always review the replayed result before continuing - see *Caveats* below.
### Inspecting and undoing recorded resolutions
```bash
git rerere status # paths with a recorded preimage in the current operation
git rerere diff # the resolution rerere is applying
git rerere forget <path> # discard a recorded resolution (e.g. a wrong one)
```
`git rerere forget` is the escape hatch when you recorded a bad resolution: it
drops the cached entry for that path so the next conflict is presented fresh.
### Seeding from existing history
If your branch already contains **merge commits** whose conflicts you resolved
before enabling `rerere`, you can backfill the cache so those resolutions are
available immediately. Git ships a helper for this in `contrib/`:
```bash
sh /path/to/git/contrib/rerere-train.sh origin/develop..HEAD
```
It replays the merge commits in the given range, reconstructs each conflict, and
records the resolution found in the merge commit.
> **Note:** this only works for resolutions captured in merge commits. A purely
> linear (rebased) history has no merge commits to learn from, so there is
> nothing to backfill - `rerere` will simply start recording from your next
> conflict onward.
### Sharing the cache (optional)
The cache is local. If you work across several machines, or want a team to share
resolutions for the same recurring conflicts, copy the directory:
```bash
rsync -a ~/work/oai-A/.git/rr-cache/ ~/work/oai-B/.git/rr-cache/
```
There is no built-in push/pull for the cache; treat it as an ordinary directory
to sync.
### Caveats and good practice
- `rerere` matches on the **exact** conflicting text. If `develop` changed the
lines surrounding your change, the preimage differs and the conflict is
presented as new. This is expected - the resolution is still recorded for the
next identical occurrence.
- A replayed resolution is only as correct as the original. When the code around
a conflict has evolved, an old resolution can apply cleanly yet be wrong.
**Review every replayed resolution and build/test before continuing.**
- `rerere` reduces repeated manual work; it does not change which branch
strategy you use. It helps both when rebasing onto `develop` and when merging
`develop` into a feature branch. Remember that branches intended for
contribution must have a linear history without merge commits (see the
[workflow policy](./code-style-contrib.md#workflow)); a fork can of course
carry merge commits if that is convenient for its development.
## See also
- [CONTRIBUTING.md](../CONTRIBUTING.md) - CLA, DCO, and licensing requirements.
- [code-style-contrib.md](./code-style-contrib.md) - workflow, commit, and
review policy, including commit trailers.
- [GET_SOURCES.md](./GET_SOURCES.md) - branches, tags, and how to obtain the
sources.
- [clang-format.md](./clang-format.md) - code formatting and its Git
integration (pre-commit hook).
- The [Git Book](https://git-scm.com/book/en/v2) and the
[`git rerere` manual](https://git-scm.com/docs/git-rerere)

Some files were not shown because too many files have changed in this diff Show More