Finalize the migration from single-cell-per-DU to the multi-cell
architecture: remove legacy DU/cell fields and refactor RRC procedures
to use cell containers and UE serving cells instead of DU-based lookups.
Data structure changes:
- Remove nr_cellid from gNB_RRC_UE_t; cell identity comes from the UE's
serving_cells (PCell entry via ue_get_pcell_entry(ue)). UE_LOG_ARGS
and LOG_UE_* macros take a PCell entry pointer for null-safe cell_id
in logs; all call sites pass ue_get_pcell_entry(ue).
- Remove setup_req, mib, sib1, mtc from nr_rrc_du_container_t (held in
cell containers); remove nr_cellid from gNB_RRC_INST and its
assignment in gnb_config.c.
Function and signature updates:
- get_ssb_arfcn(): take cell container instead of DU.
- label_intra_frequency_neighbours(): drop du parameter, use cell only.
- Handover: Handover context (source and target) now stores cell
pointers (source->cell, target->cell) instead of DU pointers. When
the context is created (N2: on Handover Request; F1: in
nr_rrc_trigger_f1_ho), the target cell is set in ho_context->target->cell
and, for F1, the source cell in ho_context->source->cell.
nr_initiate_handover() takes only source_cell and reads the target
from ho_ctx->target->cell, so it no longer takes a target parameter.
The target is known at handover creation time, while the UE’s
serving_cells are only updated after F1 UE Context Setup Response.
- nr_rrc_trigger_f1_ho() and the N2 handover path pass cell pointers
and set ho_context->target->cell (and for F1, source->cell) when
the handover is triggered.
Procedure refactoring:
- Lookups: replace get_du_by_cell_id() with get_cell_by_cell_id()/
get_cell_by_pci(); remove get_du_by_cell_id() and
get_cell_information_by_phycellId().
Rationale: cell-specific data (MIB, SIB1, mtc, info) now lives in
cell containers, and a DU can host multiple cells. Callers need the
cell (to use cell->info, cell->mtc, etc.), not the DU. Looking up
by cell_id therefore returns the cell container
(get_cell_by_cell_id()); when the DU is needed, use
cell->assoc_id and get_du_by_assoc_id(). Looking up by PCI is
scoped (e.g. get_cell_by_pci_for_du() for a given DU, or via the
UE’s serving cells) because PCI is not globally unique.
- Setup/Reestablishment: resolve cell, register as PCell via
rrc_add_ue_serving_cell(); reestablishment resolves cell by PCI
(rrc_get_cell_by_pci_for_du), then rrc_remove_ue_scells_from_du +
rrc_add_ue_serving_cell; validate_ue_cell_association() after update.
- Measurement config: use cell->info (SCS/band) and cell->mtc.
- Handover: use cell containers end-to-end; after UE context
modification response call nr_rrc_update_cell_assoc_after_ho().
- NGAP: cell_id and TAC from UE PCell via rrc_get_pcell_for_ue();
Handover Notify: get cell for message content, use get_du_for_ue() for
DU existence check; paging resolves UE by 5G-S-TMSI-Part1 and uses that
UE's PCell (rrc_get_pcell_for_ue) for F1AP_PAGING_IND nr_cellid.
Performance and robustness:
- Use rrc_get_pcell_for_ue() when cell data is needed; use
get_du_for_ue() when only the DU is needed (F1/N2 HO trigger,
Handover Notify DU check) for efficiency.
- Reestablishment: remove old PCell before adding new; error handling
for PCell add and validation.
Code cleanup:
- F1 setup: stop copying/storing setup request in DU container; F1
disconnect only frees cell containers via rrc_free_cell_container().
- dump_du_info(): iterate du->cells and show all cells per DU.
- telnetsrv_ci.c: use du->gNB_DU_id directly and fix format (%ld).
- UeContextSetupRequest servCellIndex set to RRC_PCELL_INDEX; remove
servCellIndex from F1AP UE context modification request.