RRC: auto-generate release request when no AMF

Mark non-existing AMF UE NGAP ID through invalid INT64_MAX number
(permitted range is up to 2^40-1). Check for this range in the RAN
function, as we might otherwise pass the invalid AMF UE NGAP ID to the
agent, which would assert with

   nr-softmodem: /oai-ran/openair2/E2AP/flexric/src/lib/3gpp/enc/enc_gnb.c:83: enc_gNB_UE_asn: Assertion `gnb->amf_ue_ngap_id < 1UL << 40' failed.

In other words, don't send KPM messages for a UE which has no valid AMF
UE NGAP ID yet (which follows from the fact that the spec requires an
AMF UE NGAP ID; the previous behavior of simply sending 0 could be
considered a bug, because it's not the UE's true AMF UE NGAP ID).
This commit is contained in:
Robert Schmidt
2025-07-04 09:40:26 +02:00
parent 75be2a1a59
commit 67e9c9c263
4 changed files with 20 additions and 5 deletions
@@ -30,7 +30,12 @@ ue_id_e2sm_t fill_e2sm_gnb_ue_id_data(const gNB_RRC_UE_t *rrc_ue_context, __attr
// 6.2.3.16
// Mandatory
// AMF UE NGAP ID
ue_id.gnb.amf_ue_ngap_id = rrc_ue_context->amf_ue_ngap_id;
// it seems that certain messages can be triggered before the ue has an AMF
// UE NGAP ID (e.g., RRC setup). In that case, the AMF UE NGAP ID is set to
// an invalid value. Below, check for this, and set 0 in that case (which
// historically used to be in amf_ue_ngap_id).
uint64_t auni = rrc_ue_context->amf_ue_ngap_id;
ue_id.gnb.amf_ue_ngap_id = auni < (1LL << 40) ? auni : 0;
// Mandatory
//GUAMI 6.2.3.17
@@ -209,6 +209,9 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_cu(const test_info_lst_t test_info)
struct rrc_gNB_ue_context_s* rrc_ue_context = NULL;
RB_FOREACH(rrc_ue_context, rrc_nr_ue_tree_s, &RC.nrrrc[0]->rrc_ue_head) {
gNB_RRC_UE_t *ue = &rrc_ue_context->ue_context;
/* UE has no AMF UE NGAP ID yet => can't send message */
if (ue->amf_ue_ngap_id >= (1LL << 40))
continue;
for (int p = 0; p < ue->nb_of_pdusessions; ++p) {
pdusession_t *pdu = &ue->pduSession[p].param;
if (nssai_matches(pdu->nssai, sst, sd)) {
@@ -296,6 +299,9 @@ static arr_ue_id_t filter_ues_by_s_nssai_in_du_or_monolithic(const test_info_lst
arr_ue_id.ue_id[arr_ue_id.sz] = fill_ue_id_data[ngran_gNB_DU](NULL, rrc_ue_id.secondary_ue, 0);
} else {
rrc_gNB_ue_context_t* rrc_ue_context = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[0], -1, ue->rnti);
/* UE has no AMF UE NGAP ID yet => can't send message */
if (rrc_ue_context->ue_context.amf_ue_ngap_id >= (1LL << 40))
continue;
arr_ue_id.ue_id[arr_ue_id.sz] = fill_ue_id_data[ngran_gNB](&rrc_ue_context->ue_context, 0, 0);
}
+6 -4
View File
@@ -2146,12 +2146,14 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p, sctp_as
f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_CU_ue_id);
// TODO what happens if no AMF connected? should also handle, set an_release true
int srbid = 1;
if (!ue_context_p) {
LOG_W(RRC, "could not find UE context for CU UE ID %u: auto-generate release command\n", req->gNB_CU_ue_id);
// valid AMF UE NGAP ID range is 0..2^40-1
if (!ue_context_p || ue_context_p->ue_context.amf_ue_ngap_id >= (1LL << 40)) {
const char *reason = !ue_context_p ? "could not find UE context" : "no AMF";
LOG_W(RRC, "%s for CU UE ID %u: auto-generate release command\n", reason, req->gNB_CU_ue_id);
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(0));
RETURN_IF_INVALID_ASSOC_ID(assoc_id);
f1ap_ue_context_release_cmd_t ue_context_release_cmd = {
.gNB_CU_ue_id = req->gNB_CU_ue_id,
.gNB_DU_ue_id = req->gNB_DU_ue_id,
@@ -2159,7 +2161,7 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p, sctp_as
.cause_value = 10, // 10 = F1AP_CauseRadioNetwork_normal_release
.srb_id = srbid,
};
deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd};
deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = assoc_id};
nr_pdcp_data_req_srb(req->gNB_CU_ue_id, srbid, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
return;
}
+2
View File
@@ -200,6 +200,8 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
ue->rnti = rnti;
ue->random_ue_identity = ue_identityP;
// signal "no AMF UE NGAP ID" because valid range is 0..2^40-1
ue->amf_ue_ngap_id = INT64_MAX;
f1_ue_data_t ue_data = {.secondary_ue = du_ue_id, .du_assoc_id = assoc_id};
AssertFatal(!cu_exists_f1_ue_data(ue->rrc_ue_id),
"UE F1 Context for ID %d already exists, logic bug\n",