mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Merge remote-tracking branch 'GuidoCasati/rrc-fixes' into integration_2026_w28
RRC fixes (#225) - Hardens NR RRC re-establishment handling on the gNB and UE: re-establishment requests with invalid PCI/C-RNTI or incomplete UE context are rejected or fall back to RRCSetup per TS 38.33. - Fixes an invalid post-release connected state after PDU session teardown - Stops gNB process aborts when a UE sends spare RRC establishment-cause values. - Fix RRCSetup fallback: the UE MAC layer is reset before bearer teardown on RRCSetup fallback to avoid scheduler use of released RLC entities. Closes: #127 Closes: #128 Closes: #148 Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org> Reviewed-by: Francesco Mani <email@francescomani.it>
This commit is contained in:
@@ -57,6 +57,8 @@
|
|||||||
/** Maximum number of Paging Occasions per Paging Frame (TS 38.331 PCCH-Config) */
|
/** Maximum number of Paging Occasions per Paging Frame (TS 38.331 PCCH-Config) */
|
||||||
#define NR_PCCH_MAX_PO 4
|
#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_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 */
|
#define NB_RAB_MAX 11 /* from LTE_maxDRB in LTE_asn_constant.h */
|
||||||
|
|||||||
@@ -1901,6 +1901,12 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t
|
|||||||
mac->state = UE_BARRED;
|
mac->state = UE_BARRED;
|
||||||
break;
|
break;
|
||||||
case RRC_SETUP_REESTAB_RESUME:
|
case RRC_SETUP_REESTAB_RESUME:
|
||||||
|
for (int i = mac->lc_ordered_list.count; i > 0; i--) {
|
||||||
|
nr_lcordered_info_t *lc = mac->lc_ordered_list.array[i - 1];
|
||||||
|
if (lc->rb.type == NR_LCID_SRB && lc->rb.choice.srb_id == 0)
|
||||||
|
continue;
|
||||||
|
asn_sequence_del(&mac->lc_ordered_list, i - 1, 1);
|
||||||
|
}
|
||||||
release_mac_configuration(mac, cause);
|
release_mac_configuration(mac, cause);
|
||||||
nr_ue_mac_default_configs(mac);
|
nr_ue_mac_default_configs(mac);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -96,6 +96,13 @@ mui_t rrc_gNB_mui = 0;
|
|||||||
/* Per-transaction max_delays counter to limit retry attempts */
|
/* Per-transaction max_delays counter to limit retry attempts */
|
||||||
#define MAX_DELAYS 100
|
#define MAX_DELAYS 100
|
||||||
|
|
||||||
|
/* C-RNTI range (0001-FFF2) (TS 38.321 Table 7.1-1, Rel-16+) */
|
||||||
|
#define NR_C_RNTI_MIN 0x0001
|
||||||
|
#define NR_C_RNTI_MAX 0xfff2
|
||||||
|
|
||||||
|
/* 5.3.3.3 TS 38.331: Random UE identity mask for 39-bit values */
|
||||||
|
#define NR_RRC_RANDOM_VALUE_39_BIT_MASK (0x7fffffffffULL)
|
||||||
|
|
||||||
/** @brief clone and re-enqueue an NGAP message after delaying
|
/** @brief clone and re-enqueue an NGAP message after delaying
|
||||||
* delays the ongoing transaction (in msg_p) by setting a timer to wait
|
* delays the ongoing transaction (in msg_p) by setting a timer to wait
|
||||||
* 10ms; upon expiry, delivers to RRC, which sends the message to itself */
|
* 10ms; upon expiry, delivers to RRC, which sends the message to itself */
|
||||||
@@ -1084,9 +1091,8 @@ static DRB_nGRAN_to_mod_t get_e1_drb_mod_reestablishment(const drb_t *drb, const
|
|||||||
return drb_e1;
|
return drb_e1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @brief Re-establish DRB PDCP on CU-UP (TS 38.331 clause 5.3.5.6.5, TS 38.463 bearer mod).
|
||||||
* @brief Notify E1 re-establishment to CU-UP
|
* Sends pDCP_Reestablishment and updated KUP keys after KgNB derivation. */
|
||||||
*/
|
|
||||||
static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||||
{
|
{
|
||||||
// Quit if no CU-UP is associated
|
// Quit if no CU-UP is associated
|
||||||
@@ -1094,6 +1100,10 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TS 38.331 §5.3.5.6.5: no DRB/PDU session (e.g. after release) means nothing to do. */
|
||||||
|
if (seq_arr_size(&ue_p->drbs) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
e1ap_bearer_mod_req_t req = {
|
e1ap_bearer_mod_req_t req = {
|
||||||
.gNB_cu_cp_ue_id = ue_p->rrc_ue_id,
|
.gNB_cu_cp_ue_id = ue_p->rrc_ue_id,
|
||||||
.gNB_cu_up_ue_id = ue_p->rrc_ue_id,
|
.gNB_cu_up_ue_id = ue_p->rrc_ue_id,
|
||||||
@@ -1431,11 +1441,20 @@ static const nr_rrc_cell_container_t *get_previous_cell_by_pci_in_du(gNB_RRC_INS
|
|||||||
return rrc_get_cell_by_pci_for_du(&du->cells, pci);
|
return rrc_get_cell_by_pci_for_du(&du->cells, pci);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Process RRCReestablishmentRequest on CCCH (TS 38.331 clause 5.3.7.4).
|
||||||
|
* On valid UE context, update RNTI and PCell and trigger RRCReestablishment, otherwise
|
||||||
|
* release any old context and send RRCSetup.
|
||||||
|
* @note Context lookup uses c-RNTI only. Out of range PhysCellId or C-RNTI are ignored. */
|
||||||
static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
||||||
sctp_assoc_t assoc_id,
|
sctp_assoc_t assoc_id,
|
||||||
const NR_RRCReestablishmentRequest_IEs_t *req,
|
const NR_RRCReestablishmentRequest_IEs_t *req,
|
||||||
const f1ap_initial_ul_rrc_message_t *msg)
|
const f1ap_initial_ul_rrc_message_t *msg)
|
||||||
{
|
{
|
||||||
|
DevAssert(req);
|
||||||
|
DevAssert(msg);
|
||||||
|
DevAssert(rrc);
|
||||||
|
RETURN_IF_INVALID_ASSOC_ID(assoc_id);
|
||||||
|
|
||||||
uint64_t random_value = 0;
|
uint64_t random_value = 0;
|
||||||
const char *scause = get_reestab_cause(req->reestablishmentCause);
|
const char *scause = get_reestab_cause(req->reestablishmentCause);
|
||||||
const long physCellId = req->ue_Identity.physCellId;
|
const long physCellId = req->ue_Identity.physCellId;
|
||||||
@@ -1450,6 +1469,18 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
|||||||
physCellId,
|
physCellId,
|
||||||
scause);
|
scause);
|
||||||
|
|
||||||
|
/* Validate PCI range per TS 38.331: PhysCellId (0..1007) */
|
||||||
|
if (physCellId < 0 || physCellId > NR_PHYS_CELL_ID_MAX) {
|
||||||
|
LOG_E(NR_RRC, "Invalid physCellId %ld (valid range: 0-%d), rejecting reestablishment request\n", physCellId, NR_PHYS_CELL_ID_MAX);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TS 38.321 Table 7.1-1: out-of-range C-RNTI, ignore request */
|
||||||
|
if (old_rnti < NR_C_RNTI_MIN || old_rnti > NR_C_RNTI_MAX) {
|
||||||
|
LOG_E(NR_RRC, "C-RNTI %04x out of range (%#04x-%#04x): rejecting RRCReestablishmentRequest\n", old_rnti, NR_C_RNTI_MIN, NR_C_RNTI_MAX);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id);
|
const nr_rrc_du_container_t *du = get_du_by_assoc_id(rrc, assoc_id);
|
||||||
if (du == NULL) {
|
if (du == NULL) {
|
||||||
LOG_E(RRC, "received CCCH message, but no corresponding DU found\n");
|
LOG_E(RRC, "received CCCH message, but no corresponding DU found\n");
|
||||||
@@ -1466,12 +1497,6 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate C-RNTI range (3GPP TS 38.321 version 15.13.0 Section 7.1 Table 7.1-1)
|
|
||||||
if (old_rnti < 0x1 || old_rnti > 0xffef) {
|
|
||||||
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI %04x range error, fallback to RRC setup\n", old_rnti);
|
|
||||||
goto fallback_rrc_setup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_cell->mtc == NULL) {
|
if (current_cell->mtc == NULL) {
|
||||||
// some UEs don't send MeasurementTimingConfiguration, so we don't know the
|
// some UEs don't send MeasurementTimingConfiguration, so we don't know the
|
||||||
// SSB ARFCN and can't do reestablishment. handle it gracefully by doing
|
// SSB ARFCN and can't do reestablishment. handle it gracefully by doing
|
||||||
@@ -1487,6 +1512,8 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TS 38.331 §5.3.7.1: retrieve UE context (C-RNTI + physCellId): if it cannot be
|
||||||
|
* retrieved, respond with RRCSetup (Fig. 5.3.7.1-2). */
|
||||||
ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, assoc_id, old_rnti);
|
ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, assoc_id, old_rnti);
|
||||||
if (ue_context_p == NULL) {
|
if (ue_context_p == NULL) {
|
||||||
// Fallback 1: Try to find UE by RNTI only (re-establishment on different DU scenario)
|
// Fallback 1: Try to find UE by RNTI only (re-establishment on different DU scenario)
|
||||||
@@ -1509,6 +1536,15 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
|||||||
goto fallback_rrc_setup;
|
goto fallback_rrc_setup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TS 38.331 5.3.7.1: requires a retrieved valid UE context. Context without
|
||||||
|
* SRB2 or any DRB is incomplete for re-establishment (UE initiation needs both,
|
||||||
|
* treat as not verified). */
|
||||||
|
if (!UE->Srb[SRB2].Active || seq_arr_size(&UE->drbs) == 0) {
|
||||||
|
LOG_E(NR_RRC, "UE context not valid for re-establishment (no SRB2/DRB), fallback to RRC setup\n");
|
||||||
|
ngap_cause = NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_NGRAN_GENERATED_REASON;
|
||||||
|
goto fallback_rrc_setup;
|
||||||
|
}
|
||||||
|
|
||||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
|
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
|
||||||
|
|
||||||
nr_ho_source_cu_t *source_ctx = UE->ho_context ? UE->ho_context->source : NULL;
|
nr_ho_source_cu_t *source_ctx = UE->ho_context ? UE->ho_context->source : NULL;
|
||||||
@@ -1617,7 +1653,7 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
|
|||||||
|
|
||||||
fallback_rrc_setup:
|
fallback_rrc_setup:
|
||||||
fill_random(&random_value, sizeof(random_value));
|
fill_random(&random_value, sizeof(random_value));
|
||||||
random_value = random_value & 0x7fffffffff; /* random value is 39 bits */
|
random_value = random_value & NR_RRC_RANDOM_VALUE_39_BIT_MASK;
|
||||||
|
|
||||||
ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = ngap_cause};
|
ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = ngap_cause};
|
||||||
/* request release of the "old" UE in case it exists */
|
/* request release of the "old" UE in case it exists */
|
||||||
|
|||||||
@@ -222,9 +222,8 @@ void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRC
|
|||||||
req->gNB_ue_ngap_id = UE->rrc_ue_id;
|
req->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||||
|
|
||||||
// RRC Establishment Cause
|
// RRC Establishment Cause
|
||||||
/* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */
|
req->establishment_cause =
|
||||||
AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d)!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST);
|
UE->establishment_cause <= NGAP_RRC_CAUSE_MCS_PRIORITY_ACCESS ? UE->establishment_cause : NGAP_RRC_CAUSE_NOTAVAILABLE;
|
||||||
req->establishment_cause = UE->establishment_cause;
|
|
||||||
|
|
||||||
// NAS-PDU
|
// NAS-PDU
|
||||||
req->nas_pdu = create_byte_array(rrcSetupComplete->dedicatedNAS_Message.size, rrcSetupComplete->dedicatedNAS_Message.buf);
|
req->nas_pdu = create_byte_array(rrcSetupComplete->dedicatedNAS_Message.size, rrcSetupComplete->dedicatedNAS_Message.buf);
|
||||||
@@ -1869,6 +1868,33 @@ void rrc_gNB_send_NGAP_HANDOVER_CANCEL(int module_id, gNB_RRC_UE_t *UE, ngap_cau
|
|||||||
itti_send_msg_to_task(TASK_NGAP, module_id, msg_p);
|
itti_send_msg_to_task(TASK_NGAP, module_id, msg_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enforce TS 38.331 §5.3.1.1 after the last DRB of a PDU session release.
|
||||||
|
* A UE is not allowed to have a configuration with SRB2 but no DRB, and vice versa.
|
||||||
|
* @note Per TS 23.502 section 4.3.4.2 step 5, NG-RAN releases PDU-session AN resources
|
||||||
|
* via RRCReconfiguration. If that leaves no DRB with SRB2 still up, request UE context
|
||||||
|
* release (TS 38.413 section 8.3.2.2). AMF UE Context Release Command triggers RRCRelease
|
||||||
|
* on the existing CU-CP path. */
|
||||||
|
static void rrc_gNB_cleanup_srb2_only_connected(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
|
||||||
|
{
|
||||||
|
DevAssert(seq_arr_size(&UE->drbs) == 0);
|
||||||
|
DevAssert(UE->Srb[SRB2].Active);
|
||||||
|
|
||||||
|
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, UE->rrc_ue_id);
|
||||||
|
if (!ue_context_p) {
|
||||||
|
LOG_W(NR_RRC, "UE %u: no RRC context for connection release after last DRB\n", UE->rrc_ue_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_I(NR_RRC, "UE %u: last DRB released with SRB2 still active: requesting RRC connection release\n", UE->rrc_ue_id);
|
||||||
|
|
||||||
|
ngap_cause_t cause = {
|
||||||
|
.type = NGAP_CAUSE_RADIO_NETWORK,
|
||||||
|
.value = NGAP_CAUSE_RADIO_NETWORK_RELEASE_DUE_TO_NGRAN_GENERATED_REASON,
|
||||||
|
};
|
||||||
|
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(rrc->module_id, ue_context_p, cause);
|
||||||
|
}
|
||||||
|
|
||||||
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
|
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
|
||||||
{
|
{
|
||||||
MessageDef *msg_p;
|
MessageDef *msg_p;
|
||||||
@@ -1893,6 +1919,10 @@ void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE
|
|||||||
|
|
||||||
LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, resp->nb_of_pdusessions_released);
|
LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, resp->nb_of_pdusessions_released);
|
||||||
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
|
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
|
||||||
|
|
||||||
|
/* TS 38.331 §5.3.1.1: cannot keep SRB2 in RRC_CONNECTED after all DRBs are gone. */
|
||||||
|
if (seq_arr_size(&UE->drbs) == 0 && UE->Srb[SRB2].Active)
|
||||||
|
rrc_gNB_cleanup_srb2_only_connected(rrc, UE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Process NG PDU Session Resource Release command (8.2.2 of 3GPP TS 38.413)
|
/** @brief Process NG PDU Session Resource Release command (8.2.2 of 3GPP TS 38.413)
|
||||||
|
|||||||
@@ -2147,7 +2147,7 @@ static void rrc_ue_generate_RRCSetupComplete(NR_UE_RRC_INST_t *rrc, const uint8_
|
|||||||
static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
|
static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
|
||||||
{
|
{
|
||||||
LOG_W(NR_RRC,
|
LOG_W(NR_RRC,
|
||||||
"[UE %ld] Recived RRCSetup in response to %s request\n",
|
"[UE %ld] Received RRCSetup in response to %s request\n",
|
||||||
rrc->ue_id, rrc->ra_trigger == RRC_CONNECTION_REESTABLISHMENT ? "RRCReestablishment" : "RRCResume");
|
rrc->ue_id, rrc->ra_trigger == RRC_CONNECTION_REESTABLISHMENT ? "RRCReestablishment" : "RRCResume");
|
||||||
|
|
||||||
// discard any stored UE Inactive AS context and suspendConfig
|
// discard any stored UE Inactive AS context and suspendConfig
|
||||||
@@ -2159,8 +2159,15 @@ static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
|
|||||||
memset(rrc->kgnb, 0, sizeof(rrc->kgnb));
|
memset(rrc->kgnb, 0, sizeof(rrc->kgnb));
|
||||||
rrc->as_security_activated = false;
|
rrc->as_security_activated = false;
|
||||||
|
|
||||||
|
// release the RRC configuration except for the default L1 parameter values,
|
||||||
|
// default MAC Cell Group configuration and CCCH configuration
|
||||||
|
nr_mac_rrc_message_t rrc_msg = {0};
|
||||||
|
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
||||||
|
rrc_msg.payload.config_reset.cause = RRC_SETUP_REESTAB_RESUME;
|
||||||
|
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
||||||
|
|
||||||
// release radio resources for all established RBs except SRB0,
|
// release radio resources for all established RBs except SRB0,
|
||||||
// including release of the RLC entities, of the associated PDCP entities and of SDAP
|
// including release of the associated PDCP entities and of SDAP
|
||||||
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
|
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
|
||||||
if (get_DRB_status(rrc, i) != RB_NOT_PRESENT) {
|
if (get_DRB_status(rrc, i) != RB_NOT_PRESENT) {
|
||||||
set_DRB_status(rrc, i, RB_NOT_PRESENT);
|
set_DRB_status(rrc, i, RB_NOT_PRESENT);
|
||||||
@@ -2178,15 +2185,6 @@ static void nr_rrc_rrcsetup_fallback(NR_UE_RRC_INST_t *rrc)
|
|||||||
}
|
}
|
||||||
nr_sdap_delete_ue_entities(rrc->ue_id);
|
nr_sdap_delete_ue_entities(rrc->ue_id);
|
||||||
|
|
||||||
// release the RRC configuration except for the default L1 parameter values,
|
|
||||||
// default MAC Cell Group configuration and CCCH configuration
|
|
||||||
// TODO to be completed
|
|
||||||
NR_UE_MAC_reset_cause_t cause = RRC_SETUP_REESTAB_RESUME;
|
|
||||||
nr_mac_rrc_message_t rrc_msg = {0};
|
|
||||||
rrc_msg.payload_type = NR_MAC_RRC_CONFIG_RESET;
|
|
||||||
rrc_msg.payload.config_reset.cause = cause;
|
|
||||||
nr_rrc_send_msg_to_mac(rrc, &rrc_msg);
|
|
||||||
|
|
||||||
// indicate to upper layers fallback of the RRC connection
|
// indicate to upper layers fallback of the RRC connection
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,16 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng
|
|||||||
return amf;
|
return amf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief Map UE EstablishmentCause (TS 38.331) to NGAP RRCEstablishmentCause (clause 9.3.1.111).
|
||||||
|
* Values 0-9 pass through, otherwise return notAvailable. */
|
||||||
|
static NGAP_RRCEstablishmentCause_t rrc2ngap_establishment_cause(ngap_rrc_establishment_cause_t cause)
|
||||||
|
{
|
||||||
|
if (cause <= NGAP_RRC_CAUSE_MCS_PRIORITY_ACCESS)
|
||||||
|
return cause;
|
||||||
|
/* clause 9.3.1.111: notAvailable when the UE cause does not map to any other value */
|
||||||
|
return NGAP_RRCEstablishmentCause_notAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief NAS Transport Messages: Initial UE Message
|
/** @brief NAS Transport Messages: Initial UE Message
|
||||||
* forward the first received (layer 3) uplink NAS message
|
* forward the first received (layer 3) uplink NAS message
|
||||||
* from the radio interface to the AMF over N2
|
* from the radio interface to the AMF over N2
|
||||||
@@ -201,16 +211,13 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
|
|||||||
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
|
MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the establishment cause according to those provided by RRC */
|
|
||||||
DevCheck(UEfirstReq->establishment_cause < NGAP_RRC_CAUSE_LAST, UEfirstReq->establishment_cause, NGAP_RRC_CAUSE_LAST, 0);
|
|
||||||
|
|
||||||
// RRC Establishment Cause (M)
|
// RRC Establishment Cause (M)
|
||||||
{
|
{
|
||||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie);
|
asn1cSequenceAdd(out->protocolIEs.list, NGAP_InitialUEMessage_IEs_t, ie);
|
||||||
ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause;
|
ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause;
|
||||||
ie->criticality = NGAP_Criticality_ignore;
|
ie->criticality = NGAP_Criticality_ignore;
|
||||||
ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause;
|
ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause;
|
||||||
ie->value.choice.RRCEstablishmentCause = UEfirstReq->establishment_cause;
|
ie->value.choice.RRCEstablishmentCause = rrc2ngap_establishment_cause(UEfirstReq->establishment_cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5G-S-TMSI (O)
|
// 5G-S-TMSI (O)
|
||||||
|
|||||||
Reference in New Issue
Block a user