Merge remote-tracking branch 'origin/redcap_support_in_gnb' into integration_2025_w29 (!3515)

Extended changes to "Initial support for RedCap" feature in gNB

Read UE RedCap capabilities.
This commit is contained in:
Robert Schmidt
2025-07-16 08:24:44 +02:00
4 changed files with 69 additions and 5 deletions
@@ -324,6 +324,12 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE,
AssertFatal(drb->qos_choice == F1AP_QOS_CHOICE_NR, "only NR QoS supported\n");
f1ap_drb_setup_t *resp_drb = &(*resp_drbs)[i];
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb, rlc_config);
if (UE->capability && UE->capability->rlc_Parameters && UE->capability->rlc_Parameters->ext2
&& UE->capability->rlc_Parameters->ext2->am_WithLongSN_RedCap_r17 == NULL) {
*rlc_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size12;
*rlc_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size12;
}
nr_rlc_add_drb(UE->rnti, drb->id, rlc_BearerConfig);
nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nr.nssai};
@@ -649,6 +655,8 @@ void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req)
resp.gNB_DU_ue_id = UE->rnti;
NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup);
// Needed for DRB Setup (e.g., RLC might reduce SN size)
UE->capability = ue_cap;
if (req->srbs_len > 0) {
resp.srbs_len = handle_ue_context_srbs_setup(UE, req->srbs_len, req->srbs, &resp.srbs, new_CellGroup, &mac->rlc_config);
@@ -665,7 +673,6 @@ void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req)
}
NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon;
UE->capability = ue_cap;
if (ue_cap != NULL && cg_configinfo == NULL) {
// store the new UE capabilities, and update the cellGroupConfig
// only to be done if we did not already update through the cg_configinfo
+8
View File
@@ -169,6 +169,13 @@ typedef enum {
RRC_UECAPABILITY_ENQUIRY,
} rrc_action_t;
typedef struct nr_redcap_ue_cap {
bool support_of_redcap_r17;
bool support_of_16drb_redcap_r17;
bool pdcp_drb_long_sn_redcap_r17;
bool rlc_am_drb_long_sn_redcap_r17;
} nr_redcap_ue_cap_t;
/* forward declaration */
typedef struct nr_handover_context_s nr_handover_context_t;
@@ -253,6 +260,7 @@ typedef struct gNB_RRC_UE_s {
int max_delays_pdu_session;
bool ongoing_pdusession_setup_request;
nr_redcap_ue_cap_t *redcap_cap;
} gNB_RRC_UE_t;
typedef struct rrc_gNB_ue_context_s {
+42
View File
@@ -117,6 +117,34 @@ typedef struct deliver_ue_ctxt_release_data_t {
sctp_assoc_t assoc_id;
} deliver_ue_ctxt_release_data_t;
const NR_RedCapParameters_r17_t *get_redcapparam_r17(NR_UE_NR_Capability_t *UE_Capability_nr)
{
if (UE_Capability_nr && UE_Capability_nr->nonCriticalExtension && UE_Capability_nr->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension
&& UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->redCapParameters_r17) {
return UE_Capability_nr->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension
->nonCriticalExtension->redCapParameters_r17;
} else
return NULL;
}
static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id)
{
DevAssert(deliver_pdu_data != NULL);
@@ -1590,6 +1618,18 @@ static void handle_ueCapabilityInformation(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE,
UE->UE_Capability_nr = 0;
}
const NR_RedCapParameters_r17_t *redcap_p = get_redcapparam_r17(UE->UE_Capability_nr);
if (redcap_p) {
UE->redcap_cap = calloc_or_fail(1, sizeof(*UE->redcap_cap));
UE->redcap_cap->support_of_redcap_r17 = redcap_p->supportOfRedCap_r17 != NULL;
UE->redcap_cap->support_of_16drb_redcap_r17 = redcap_p->supportOf16DRB_RedCap_r17 != NULL;
if (UE->UE_Capability_nr->pdcp_Parameters.ext2)
UE->redcap_cap->pdcp_drb_long_sn_redcap_r17 = UE->UE_Capability_nr->pdcp_Parameters.ext2->longSN_RedCap_r17 != NULL;
if (UE->UE_Capability_nr->rlc_Parameters && UE->UE_Capability_nr->rlc_Parameters->ext2)
UE->redcap_cap->rlc_am_drb_long_sn_redcap_r17 =
UE->UE_Capability_nr->rlc_Parameters->ext2->am_WithLongSN_RedCap_r17 != NULL;
}
UE->UE_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size;
if (eutra_index != -1) {
LOG_E(NR_RRC, "fatal: more than 1 eutra capability\n");
@@ -2200,6 +2240,8 @@ static void rrc_delete_ue_data(gNB_RRC_UE_t *UE)
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, UE->measResults);
FREE_AND_ZERO_BYTE_ARRAY(UE->ue_cap_buffer);
free_MeasConfig(UE->measConfig);
free(UE->redcap_cap);
UE->redcap_cap = NULL;
}
void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p)
+11 -4
View File
@@ -85,12 +85,19 @@ drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id)
void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config,
int do_drb_integrity,
int do_drb_ciphering,
const nr_pdcp_configuration_t *default_pdcp_config)
const nr_pdcp_configuration_t *default_pdcp_config,
const nr_redcap_ue_cap_t *redcap_cap)
{
AssertError(pdcp_config != NULL, return, "Failed to set default PDCP configuration for DRB!\n");
pdcp_config->discardTimer = encode_discard_timer(default_pdcp_config->drb.discard_timer);
pdcp_config->pdcp_SN_SizeDL = encode_sn_size_dl(default_pdcp_config->drb.sn_size);
pdcp_config->pdcp_SN_SizeUL = encode_sn_size_ul(default_pdcp_config->drb.sn_size);
if (redcap_cap && redcap_cap->support_of_redcap_r17 && !redcap_cap->pdcp_drb_long_sn_redcap_r17) {
LOG_I(NR_RRC, "UE is RedCap without long PDCP SN support: overriding PDCP SN size to 12\n");
pdcp_config->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len12bits;
pdcp_config->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len12bits;
} else {
pdcp_config->pdcp_SN_SizeDL = encode_sn_size_dl(default_pdcp_config->drb.sn_size);
pdcp_config->pdcp_SN_SizeUL = encode_sn_size_ul(default_pdcp_config->drb.sn_size);
}
pdcp_config->t_Reordering = encode_t_reordering(default_pdcp_config->drb.t_reordering);
pdcp_config->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
pdcp_config->headerCompression.NotUsed = 0;
@@ -145,7 +152,7 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue,
est_drb->status = DRB_ACTIVE;
}
/* PDCP Configuration */
set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering, pdcp_config);
set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering, pdcp_config, ue->redcap_cap);
drb_t *rrc_drb = get_drb(ue, drb_id);
DevAssert(rrc_drb == est_drb); /* to double check that we create the same which we would retrieve */