Commit 4c0fa908 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/bugfixes-gnb-stability' into integration_2024_w42 (!3038)

- Fixes #853, #854, #858, #859, #862
- handle repeated NGAP Initial context setup requests, thereby fixing assert:

      Assertion (!ue_p->as_security_active) failed!
      In rrc_gNB_generate_SecurityModeCommand() /home/eurecom/raymond/openairinterface5g/openair2/RRC/NR/rrc_gNB.c:2590
      logic error: security already activ

- A lot of cleanup: remove almost all use of protocol_ctxt_t in 5G RRC and use
  existing pointers instead
parents 5f5d8596 c4344f26
......@@ -1260,7 +1260,6 @@ set(L2_NR_SRC
${NR_PDCP_SRC}
${NR_SDAP_SRC}
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/mac_rrc_dl_direct.c
${NR_RRC_DIR}/mac_rrc_dl_f1ap.c
${NR_RRC_DIR}/nr_rrc_config.c
......
......@@ -68,9 +68,9 @@ static int get_single_ue_id(void)
* @param prnt: Print function
* @return 0 on success, -1 on failure
*/
int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt) {
int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt)
{
ue_id_t ue_id = -1;
protocol_ctxt_t ctxt;
if (!buf) {
ue_id = get_single_ue_id();
......@@ -96,10 +96,8 @@ int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt) {
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
rrc_gNB_generate_RRCRelease(rrc, UE);
prnt("RRC Release triggered for UE %u\n", ue_id);
return 0;
......@@ -108,16 +106,14 @@ int rrc_gNB_trigger_release(char *buf, int debug, telnet_printfunc_t prnt) {
/**
* @brief Trigger RRC Release for all UEs
*/
int rrc_gNB_trigger_release_all(char *buf, int debug, telnet_printfunc_t prnt) {
int rrc_gNB_trigger_release_all(char *buf, int debug, telnet_printfunc_t prnt)
{
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt; /* Not sure what exactly is this */
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[0]->rrc_ue_head)) {
gNB_RRC_INST *rrc = RC.nrrrc[0];
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) {
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
rrc_gNB_generate_RRCRelease(rrc, UE);
prnt("RRC Release triggered for UE %u\n", UE->rrc_ue_id);
}
......
......@@ -1886,13 +1886,11 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_radio_bearers.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_NGAP.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_proto.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_common.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_UE_context.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/MESSAGES/asn1_msg.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/MESSAGES/asn1_msg.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_UE_context.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/cucp_cuup_e1ap.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_common.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/nr_rrc_config.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/RRC/NR/rrc_gNB_radio_bearers.h \
......
......@@ -123,11 +123,6 @@ int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t ch
return 0;
}
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
{
abort();
}
void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig)
{
abort();
......
......@@ -142,7 +142,7 @@ void *F1AP_DU_task(void *arg) {
createF1inst(myInstance, msgSetup, nc);
du_task_send_sctp_association_req(myInstance, nc);
instance_t gtpInst = du_create_gtpu_instance_to_cu(nc);
AssertFatal(gtpInst != 0, "cannot create DU F1-U GTP module\n");
AssertFatal(gtpInst > 0, "cannot create DU F1-U GTP module\n");
getCxt(myInstance)->gtpInst = gtpInst;
DUuniqInstance = gtpInst;
} break;
......
......@@ -44,13 +44,6 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
uint8_t *inde_list
);
int
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t *const ctxt_pP,
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
uint8_t *inde_list
);
/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP)
*\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels.
*\param module_id Instance ID of eNB.
......
......@@ -519,9 +519,7 @@ int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP,
return ((enc_rval.encoded + 7) / 8);
}
int do_NR_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
int do_NR_SecurityModeCommand(uint8_t *const buffer,
const uint8_t Transaction_id,
const uint8_t cipheringAlgorithm,
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm)
......@@ -555,19 +553,13 @@ int do_NR_SecurityModeCommand(
AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg);
LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
// rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0);
// exit(-1);
return((enc_rval.encoded+7)/8);
}
/*TODO*/
//------------------------------------------------------------------------------
int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
const uint8_t Transaction_id)
//------------------------------------------------------------------------------
int do_NR_SA_UECapabilityEnquiry(uint8_t *const buffer, const uint8_t Transaction_id)
{
NR_UE_CapabilityRequestFilterNR_t *sa_band_filter;
NR_FreqBandList_t *sa_band_list;
......@@ -627,7 +619,7 @@ int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
enc_rval.failed_type->name, enc_rval.encoded);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg);
LOG_D(NR_RRC, "[gNB %d] NR UECapabilityRequest for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
LOG_D(NR_RRC, "NR UECapabilityRequestEncoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded + 7) / 8);
return((enc_rval.encoded+7)/8);
}
......
......@@ -81,16 +81,12 @@ int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP,
const gNB_RrcConfigurationReq *configuration,
NR_SRB_ToAddModList_t *SRBs);
int do_NR_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
int do_NR_SecurityModeCommand(uint8_t *const buffer,
const uint8_t Transaction_id,
const uint8_t cipheringAlgorithm,
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm);
int do_NR_SA_UECapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
const uint8_t Transaction_id);
int do_NR_SA_UECapabilityEnquiry(uint8_t *const buffer, const uint8_t Transaction_id);
int do_NR_RRCRelease(uint8_t *buffer, size_t buffer_size, uint8_t Transaction_id);
......
......@@ -37,9 +37,8 @@ TEST(nr_asn1, rrc_reject)
TEST(nr_asn1, sa_capability_enquiry)
{
protocol_ctxt_t ctxt = {0};
unsigned char buf[1000];
EXPECT_GT(do_NR_SA_UECapabilityEnquiry(&ctxt, buf, 0), 0);
EXPECT_GT(do_NR_SA_UECapabilityEnquiry(buf, 0), 0);
}
TEST(nr_asn1, rrc_reconfiguration_complete_for_nsa)
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file nr_rrc_common.c
* \brief rrc common procedures for gNB
* \author Navid Nikaein and Raymond Knopp, WEI-TAI CHEN
* \date 2011 - 2014, 2018
* \version 1.0
* \company Eurecom, NTUST
* \email: navid.nikaein@eurecom.fr and raymond.knopp@eurecom.fr, kroempa@gmail.com
*/
#include "nr_rrc_extern.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "COMMON/openair_defs.h"
#include "common/platform_types.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "LAYER2/RLC/rlc.h"
#include "COMMON/mac_rrc_primitives.h"
#include "common/utils/LOG/log.h"
#include "asn1_msg.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/ran_context.h"
#define DEBUG_NR_RRC 1
extern RAN_CONTEXT_t RC;
extern UE_MAC_INST *UE_mac_inst;
extern mui_t rrc_gNB_mui;
//-----------------------------------------------------------------------------
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan)
{
chan->transport_block_size = 4;
chan->max_transport_blocks = 16;
chan->Delay_class = 1;
return;
}
......@@ -59,6 +59,4 @@ typedef struct SRB_INFO_TABLE_ENTRY_NR_s {
uint8_t status;
} NR_SRB_INFO_TABLE_ENTRY;
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan);
#endif
......@@ -45,19 +45,6 @@
#include "NR_CellGroupConfig.h"
#define NR_MAX_SUPPORTED_DL_LAYERS 4
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan);
void rrc_gNB_process_SgNBAdditionRequest(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP
);
void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
);
rrc_gNB_ue_context_t *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP);
void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t * cg_config_info);
......@@ -72,21 +59,13 @@ NR_CG_Config_t *generate_CG_Config(const NR_RRCReconfiguration_t *reconfig, cons
int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP);
void rrc_gNB_generate_SecurityModeCommand(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p);
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
void
rrc_gNB_generate_UECapabilityEnquiry(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
);
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
void
rrc_gNB_generate_RRCRelease(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
);
void rrc_gNB_generate_RRCRelease(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
/**\brief RRC eNB task.
\param args_p Pointer on arguments to start the task. */
......@@ -100,21 +79,14 @@ void *rrc_gnb_task(void *args_p);
\ *reOffset Pointer to RE Offset Value */
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset);
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
protocol_ctxt_t *const ctxt_pP,
const int dl_bwp_id,
const int ul_bwp_id);
int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int dl_bwp_id, const int ul_bwp_id);
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
gNB_RRC_UE_t *ue_p,
uint8_t xid,
uint32_t nas_length,
uint8_t *nas_buffer);
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP);
bool ue_associated_to_cuup(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue);
sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd);
......
......@@ -471,25 +471,19 @@ static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context
/*
* Process the rrc setup complete message from UE (SRB1 Active)
*/
static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
static void rrc_gNB_process_RRCSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
//-----------------------------------------------------------------------------
{
LOG_A(NR_RRC, "UE %d Processing NR_RRCSetupComplete from UE\n", ue_context_pP->ue_context.rrc_ue_id);
ue_context_pP->ue_context.Srb[1].Active = 1;
ue_context_pP->ue_context.Srb[2].Active = 0;
AssertFatal(ctxt_pP->rntiMaybeUEid == ue_context_pP->ue_context.rrc_ue_id, "logic bug: inconsistent IDs, must use CU UE ID!\n");
LOG_A(NR_RRC, "UE %d Processing NR_RRCSetupComplete from UE\n", UE->rrc_ue_id);
UE->Srb[1].Active = 1;
UE->Srb[2].Active = 0;
rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete);
rrc_gNB_send_NGAP_NAS_FIRST_REQ(rrc, UE, rrcSetupComplete);
}
//-----------------------------------------------------------------------------
void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
//-----------------------------------------------------------------------------
static void rrc_gNB_generate_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
{
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
ue_p->xids[xid] = RRC_PDUSESSION_ESTABLISH;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
......@@ -570,29 +564,13 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
ue_p->DRB_ReleaseList = NULL;
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %d, xid %d)\n", ue_p->rrc_ue_id, size, xid);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
//-----------------------------------------------------------------------------
void
rrc_gNB_modify_dedicatedRRCReconfiguration(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP)
//-----------------------------------------------------------------------------
void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
{
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
int qos_flow_index = 0;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
ue_p->xids[xid] = RRC_PDUSESSION_MODIFY;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList =
......@@ -694,33 +672,18 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
for (int i = 0; i < ue_p->nb_of_pdusessions; i++)
clear_nas_pdu(&ue_p->pduSession[i].param.nas_pdu);
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %d)\n", ue_p->rrc_ue_id, size);
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
gNB_RRC_UE_t *ue_p,
uint8_t xid,
uint32_t nas_length,
uint8_t *nas_buffer)
//-----------------------------------------------------------------------------
{
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = CALLOC(sizeof(*DRB_Release_configList2), 1);
for (int i = 0; i < NB_RB_MAX; i++) {
......@@ -761,18 +724,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
free(nas_buffer);
}
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_p->rnti);
LOG_D(NR_RRC,
"[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
LOG_I(NR_RRC, "UE %d: Generate NR_RRCReconfiguration (bytes %d)\n", ue_p->rrc_ue_id, size);
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
......@@ -919,15 +871,8 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
}
/// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request.
/// @param ctxt_pP Protocol context containing information regarding the UE and gNB
/// @param reestablish_rnti is the old C-RNTI
/// @param ue_context_pP UE context container information regarding the UE
/// @param xid Transaction Identifier used in RRC messages
static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP,
const uint8_t xid)
static void rrc_gNB_process_RRCReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const uint8_t xid)
{
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
LOG_I(NR_RRC, "UE %d Processing NR_RRCReestablishmentComplete from UE\n", ue_p->rrc_ue_id);
int i = 0;
......@@ -936,7 +881,6 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
ue_p->Srb[1].Active = 1;
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig;
......@@ -982,7 +926,7 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
/* Create drb-ToAddModList */
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true);
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE;
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ue_p,
......@@ -1010,13 +954,9 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
}
//-----------------------------------------------------------------------------
int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
protocol_ctxt_t *const ctxt_pP,
const int dl_bwp_id,
const int ul_bwp_id)
int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int dl_bwp_id, const int ul_bwp_id)
{
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
ue_p->xids[xid] = RRC_DEDICATED_RECONF;
NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup;
......@@ -1031,7 +971,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t buffer[NR_RRC_BUF_SIZE];
int size = do_RRCReconfiguration(ue_p, buffer, NR_RRC_BUF_SIZE, xid, NULL, NULL, NULL, NULL, NULL, NULL, masterCellGroup);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
return 0;
......@@ -1207,10 +1146,8 @@ fallback_rrc_setup:
return;
}
static void process_Periodical_Measurement_Report(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
static void process_Periodical_Measurement_Report(gNB_RRC_UE_t *ue_ctxt, NR_MeasurementReport_t *measurementReport)
{
// LOG_I(NR_RRC, "Periodical Event Report! Do Nothing for now...\n");
gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context;
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, ue_ctxt->measResults);
ue_ctxt->measResults = NULL;
......@@ -1300,19 +1237,21 @@ static void process_Event_Based_Measurement_Report(NR_ReportConfigNR_t *report,
}
}
static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, NR_MeasurementReport_t *measurementReport)
static void rrc_gNB_process_MeasurementReport(gNB_RRC_UE_t *UE, NR_MeasurementReport_t *measurementReport)
{
LOG_D(NR_RRC, "Process Measurement Report\n");
NR_MeasurementReport__criticalExtensions_PR p = measurementReport->criticalExtensions.present;
if (p != NR_MeasurementReport__criticalExtensions_PR_measurementReport
|| measurementReport->criticalExtensions.choice.measurementReport == NULL) {
LOG_E(NR_RRC, "UE %d: expected presence of MeasurementReport, but has %d (%p)\n", UE->rrc_ue_id, p, measurementReport->criticalExtensions.choice.measurementReport);
return;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1))
xer_fprint(stdout, &asn_DEF_NR_MeasurementReport, (void *)measurementReport);
DevAssert(measurementReport->criticalExtensions.present == NR_MeasurementReport__criticalExtensions_PR_measurementReport
&& measurementReport->criticalExtensions.choice.measurementReport != NULL);
gNB_RRC_UE_t *ue_ctxt = &ue_context->ue_context;
NR_MeasConfig_t *meas_config = ue_ctxt->measConfig;
NR_MeasConfig_t *meas_config = UE->measConfig;
if (meas_config == NULL) {
LOG_I(NR_RRC, "Unexpected Measurement Report from UE with id: %d\n", ue_ctxt->rrc_ue_id);
LOG_I(NR_RRC, "Unexpected Measurement Report from UE with id: %d\n", UE->rrc_ue_id);
return;
}
......@@ -1347,7 +1286,7 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
}
if (report_config->choice.reportConfigNR->reportType.present == NR_ReportConfigNR__reportType_PR_periodical)
return process_Periodical_Measurement_Report(ue_context, measurementReport);
return process_Periodical_Measurement_Report(UE, measurementReport);
if (report_config->choice.reportConfigNR->reportType.present != NR_ReportConfigNR__reportType_PR_eventTriggered) {
LOG_D(NR_RRC, "Incoming Report Type: %d is not supported! \n", report_config->choice.reportConfigNR->reportType.present);
......@@ -1357,28 +1296,26 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
process_Event_Based_Measurement_Report(report_config->choice.reportConfigNR, measurementReport);
}
static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_p,
const NR_RRCReestablishmentComplete_t *reestablishment_complete)
static int handle_rrcReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_RRCReestablishmentComplete_t *cplt)
{
DevAssert(ue_context_p != NULL);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
DevAssert(reestablishment_complete->criticalExtensions.present
== NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete);
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, ue_context_p, reestablishment_complete->rrc_TransactionIdentifier);
NR_RRCReestablishmentComplete__criticalExtensions_PR p = cplt->criticalExtensions.present;
if (p != NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) {
LOG_E(NR_RRC, "UE %d: expected presence of rrcReestablishmentComplete, but message has %d\n", UE->rrc_ue_id, p);
return -1;
}
rrc_gNB_process_RRCReestablishmentComplete(rrc, UE, cplt->rrc_TransactionIdentifier);
UE->ue_reestablishment_counter++;
return 0;
}
static void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
{
if (UE->nas_pdu.buffer == NULL || UE->nas_pdu.length == 0)
return; // no problem: the UE will re-request a NAS PDU
uint8_t buffer[4096];
unsigned int xid = rrc_gNB_get_next_transaction_identifier(0);
unsigned int xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
uint32_t length = do_NR_DLInformationTransfer(buffer, sizeof(buffer), xid, UE->nas_pdu.length, UE->nas_pdu.buffer);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n");
rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH;
......@@ -1388,16 +1325,15 @@ static void rrc_forward_ue_nas_message(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
UE->nas_pdu.length = 0;
}
static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_p,
const NR_UECapabilityInformation_t *ue_cap_info)
static void handle_ueCapabilityInformation(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UECapabilityInformation_t *ue_cap_info)
{
AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
int xid = ue_cap_info->rrc_TransactionIdentifier;
DevAssert(UE->xids[xid] == RRC_UECAPABILITY_ENQUIRY);
rrc_action_t a = UE->xids[xid];
UE->xids[xid] = RRC_ACTION_NONE;
if (a != RRC_UECAPABILITY_ENQUIRY) {
LOG_E(NR_RRC, "UE %d: received unsolicited UE Capability Information, aborting procedure\n", UE->rrc_ue_id);
return;
}
LOG_I(NR_RRC, "UE %d: received UE capabilities (xid %d)\n", UE->rrc_ue_id, xid);
int eutra_index = -1;
......@@ -1414,7 +1350,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
(void **)&UE->ue_cap_buffer.buf);
if (UE->ue_cap_buffer.len <= 0) {
LOG_E(RRC, "could not encode UE-CapabilityRAT-ContainerList, abort handling capabilities\n");
return -1;
return;
}
for (int i = 0; i < ue_CapabilityRAT_ContainerList->list.count; i++) {
......@@ -1437,10 +1373,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
}
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT " Failed to decode nr UE capabilities (%zu bytes)\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
dec_rval.consumed);
LOG_E(NR_RRC, "UE %d: Failed to decode nr UE capabilities (%zu bytes)\n", UE->rrc_ue_id, dec_rval.consumed);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
UE->UE_Capability_nr = 0;
}
......@@ -1448,7 +1381,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
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");
exit(1);
return;
}
eutra_index = i;
}
......@@ -1471,10 +1404,7 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
}
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_FMT " Failed to decode nr UE capabilities (%zu bytes)\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
dec_rval.consumed);
LOG_E(NR_RRC, "UE %d: Failed to decode nr UE capabilities (%zu bytes)\n", UE->rrc_ue_id, dec_rval.consumed);
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
UE->UE_Capability_MRDC = 0;
}
......@@ -1487,41 +1417,33 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
}
if (eutra_index == -1)
return -1;
return;
}
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ue_cap_info);
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(rrc, UE, ue_cap_info);
if (UE->n_initial_pdu > 0) {
/* there were PDU sessions with the NG UE Context setup, but we had to set
* up security and request capabilities, so trigger PDU sessions now. The
* UE NAS message will be forwarded in the corresponding reconfiguration,
* the Initial context setup response after reconfiguration complete. */
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
} else {
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
rrc_forward_ue_nas_message(RC.nrrrc[ctxt_pP->instance], UE);
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
rrc_forward_ue_nas_message(rrc, UE);
}
return 0;
return;
}
static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_p,
const NR_RRCSetupComplete_t *setup_complete)
static void handle_rrcSetupComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_RRCSetupComplete_t *setup_complete)
{
if (!ue_context_p) {
LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
return -1;
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
uint8_t xid = setup_complete->rrc_TransactionIdentifier;
UE->xids[xid] = RRC_ACTION_NONE;
if (setup_complete->criticalExtensions.present != NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) {
LOG_E(NR_RRC, "malformed RRCSetupComplete received from UE %lx\n", ctxt_pP->rntiMaybeUEid);
return -1;
LOG_E(NR_RRC, "malformed RRCSetupComplete received from UE %d\n", UE->rrc_ue_id);
return;
}
NR_RRCSetupComplete_IEs_t *setup_complete_ies = setup_complete->criticalExtensions.choice.rrcSetupComplete;
......@@ -1532,7 +1454,7 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
const BIT_STRING_t *part2 = &setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2;
if (part2->size != 2) {
LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", part2->size);
return -1;
return;
}
if (UE->Initialue_identity_5g_s_TMSI.presence) {
......@@ -1548,7 +1470,7 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
const NR_NG_5G_S_TMSI_t *bs_stmsi = &setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI;
if (bs_stmsi->size != 6) {
LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", bs_stmsi->size);
return -1;
return;
}
fiveg_s_TMSI = BIT_STRING_to_uint64(bs_stmsi);
......@@ -1576,18 +1498,12 @@ static int handle_rrcSetupComplete(const protocol_ctxt_t *const ctxt_pP,
}
}
rrc_gNB_process_RRCSetupComplete(ctxt_pP, ue_context_p, setup_complete->criticalExtensions.choice.rrcSetupComplete);
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " UE State = NR_RRC_CONNECTED \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
return 0;
rrc_gNB_process_RRCSetupComplete(rrc, UE, setup_complete->criticalExtensions.choice.rrcSetupComplete);
return;
}
static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_p,
const NR_RRCReconfigurationComplete_t *reconfig_complete)
static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_RRCReconfigurationComplete_t *reconfig_complete)
{
AssertFatal(ue_context_p != NULL, "Processing %s() for UE %lx, ue_context_p is NULL\n", __func__, ctxt_pP->rntiMaybeUEid);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
uint8_t xid = reconfig_complete->rrc_TransactionIdentifier;
UE->ue_reconfiguration_counter++;
LOG_I(NR_RRC, "UE %d: Receive RRC Reconfiguration Complete message (xid %d)\n", UE->rrc_ue_id, xid);
......@@ -1595,22 +1511,22 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
switch (UE->xids[xid]) {
case RRC_PDUSESSION_RELEASE: {
gtpv1u_gnb_delete_tunnel_req_t req = {0};
gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req);
gtpv1u_delete_ngu_tunnel(rrc->module_id, &req);
// NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(rrc, UE, xid);
} break;
case RRC_PDUSESSION_ESTABLISH:
if (UE->n_initial_pdu > 0) {
/* PDU sessions through initial UE context setup */
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
UE->n_initial_pdu = 0;
free(UE->initial_pdus);
UE->initial_pdus = NULL;
} else if (UE->nb_of_pdusessions > 0)
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, xid);
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(rrc, UE, xid);
break;
case RRC_PDUSESSION_MODIFY:
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, ue_context_p, xid);
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(rrc, UE, xid);
break;
case RRC_REESTABLISH_COMPLETE:
case RRC_DEDICATED_RECONF:
......@@ -1630,42 +1546,45 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
}
}
}
//-----------------------------------------------------------------------------
int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
const rb_id_t Srb_id,
const uint8_t *const Rx_sdu,
const sdu_size_t sdu_sizeP)
//-----------------------------------------------------------------------------
static void rrc_gNB_generate_UECapabilityEnquiry(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue)
{
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
uint8_t buffer[100];
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(rrc->module_id), T_INT(0), T_INT(0), T_INT(ue->rrc_ue_id));
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
ue->xids[xid] = RRC_UECAPABILITY_ENQUIRY;
int size = do_NR_SA_UECapabilityEnquiry(buffer, xid);
LOG_I(NR_RRC, "UE %d: Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d, xid %d)\n", ue->rrc_ue_id, size, xid);
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size);
}
static int rrc_gNB_decode_dcch(gNB_RRC_INST *rrc, const f1ap_ul_rrc_message_t *msg)
{
/* we look up by CU UE ID! Do NOT change back to RNTI! */
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, msg->gNB_CU_ue_id);
if (!ue_context_p) {
LOG_E(RRC, "could not find UE context for CU UE ID %lu, aborting transaction\n", ctxt_pP->rntiMaybeUEid);
LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", msg->gNB_CU_ue_id);
return -1;
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if ((Srb_id != 1) && (Srb_id != 2)) {
LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id);
} else {
LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
}
LOG_D(NR_RRC, "Decoding UL-DCCH Message\n");
{
for (int i = 0; i < sdu_sizeP; i++) {
LOG_T(NR_RRC, "%x.", Rx_sdu[i]);
}
LOG_T(NR_RRC, "\n");
if (msg->srb_id < 1 || msg->srb_id > 2) {
LOG_E(NR_RRC, "Received message on SRB %d, discarding message\n", msg->srb_id);
return -1;
}
LOG_D(NR_RRC, "UE %d: Decoding DCCH %d size %d\n", UE->rrc_ue_id, msg->srb_id, msg->rrc_container_length);
LOG_DUMPMSG(RRC, DEBUG_RRC, (char *)msg->rrc_container, msg->rrc_container_length, "[MSG] RRC UL Information Transfer \n");
NR_UL_DCCH_Message_t *ul_dcch_msg = NULL;
asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_DCCH_Message, (void **)&ul_dcch_msg, Rx_sdu, sdu_sizeP, 0, 0);
asn_dec_rval_t dec_rval =
uper_decode(NULL, &asn_DEF_NR_UL_DCCH_Message, (void **)&ul_dcch_msg, msg->rrc_container, msg->rrc_container_length, 0, 0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(NR_RRC, "Failed to decode UL-DCCH (%zu bytes)\n", dec_rval.consumed);
LOG_E(NR_RRC, "UE %d: Failed to decode UL-DCCH (%zu bytes)\n", UE->rrc_ue_id, dec_rval.consumed);
return -1;
}
......@@ -1680,102 +1599,55 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
handle_rrcReconfigurationComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete);
handle_rrcReconfigurationComplete(rrc, UE, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete);
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete:
if (handle_rrcSetupComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete) == -1)
return -1;
handle_rrcSetupComplete(rrc, UE, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete);
break;
case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
DevAssert(ul_dcch_msg != NULL
&& ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1
&& ul_dcch_msg->message.choice.c1
&& ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_measurementReport);
rrc_gNB_process_MeasurementReport(ue_context_p, ul_dcch_msg->message.choice.c1->choice.measurementReport);
rrc_gNB_process_MeasurementReport(UE, ul_dcch_msg->message.choice.c1->choice.measurementReport);
break;
case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
LOG_D(NR_RRC, "Recived RRC GNB UL Information Transfer \n");
if (!ue_context_p) {
LOG_W(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
break;
}
LOG_D(NR_RRC, "[MSG] RRC UL Information Transfer \n");
LOG_DUMPMSG(RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] RRC UL Information Transfer \n");
rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg);
rrc_gNB_send_NGAP_UPLINK_NAS(rrc, UE, ul_dcch_msg);
break;
case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete:
// to avoid segmentation fault
if (!ue_context_p) {
LOG_I(NR_RRC, "Processing securityModeComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
break;
}
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT " received securityModeComplete on UL-DCCH %d from UE\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH);
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT
" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(securityModeComplete) ---> RRC_eNB\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH,
sdu_sizeP);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
/* configure ciphering */
nr_rrc_pdcp_config_security(ctxt_pP, ue_context_p, 1);
ue_context_p->ue_context.as_security_active = true;
nr_rrc_pdcp_config_security(UE, true);
UE->as_security_active = true;
/* trigger UE capability enquiry if we don't have them yet */
if (ue_context_p->ue_context.ue_cap_buffer.len == 0) {
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
if (UE->ue_cap_buffer.len == 0) {
rrc_gNB_generate_UECapabilityEnquiry(rrc, UE);
/* else blocks are executed after receiving UE capability info */
} else if (ue_context_p->ue_context.n_initial_pdu > 0) {
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
} else if (UE->n_initial_pdu > 0) {
/* there were PDU sessions with the NG UE Context setup, but we had
* to set up security, so trigger PDU sessions now. The UE NAS
* message will be forwarded in the corresponding reconfiguration,
* the Initial context setup response after reconfiguration complete. */
trigger_bearer_setup(gnb_rrc_inst, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
} else {
/* we already have capabilities, and no PDU sessions to setup, ack
* this UE */
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
rrc_forward_ue_nas_message(RC.nrrrc[0], &ue_context_p->ue_context);
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
rrc_forward_ue_nas_message(rrc, UE);
}
break;
case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure:
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR RRC Security Mode Failure\n");
LOG_E(NR_RRC, "UE %d: received securityModeFailure\n", ue_context_p->ue_context.rrc_ue_id);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
LOG_W(NR_RRC, "Cannot continue as no AS security is activated (implementation missing)\n");
break;
case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
if (handle_ueCapabilityInformation(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation)
== -1)
return -1;
handle_ueCapabilityInformation(rrc, UE, ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation);
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
if (handle_rrcReestablishmentComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete)
== -1)
return -1;
handle_rrcReestablishmentComplete(rrc, UE, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete);
break;
default:
......@@ -1973,8 +1845,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
e1_send_bearer_updates(rrc, UE, resp->drbs_to_be_setup_length, resp->drbs_to_be_setup);
}
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance};
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
rrc_gNB_generate_dedicatedRRCReconfiguration(rrc, UE);
}
static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p)
......@@ -2043,8 +1914,7 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p)
static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance)
{
f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p);
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->gNB_CU_ue_id, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
gNB_RRC_INST *rrc = RC.nrrrc[instance];
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, resp->gNB_CU_ue_id);
if (!ue_context_p) {
LOG_E(RRC, "could not find UE context for CU UE ID %u, aborting transaction\n", resp->gNB_CU_ue_id);
......@@ -2072,15 +1942,14 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
}
UE->masterCellGroup = cellGroupConfig;
rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
rrc_gNB_generate_dedicatedRRCReconfiguration(rrc, UE);
}
}
static void rrc_CU_process_ue_modification_required(MessageDef *msg_p)
static void rrc_CU_process_ue_modification_required(MessageDef *msg_p, instance_t instance)
{
gNB_RRC_INST *rrc = RC.nrrrc[instance];
f1ap_ue_context_modif_required_t *required = &F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(msg_p);
protocol_ctxt_t ctxt = {.rntiMaybeUEid = required->gNB_CU_ue_id, .module_id = 0, .instance = 0, .enb_flag = 1, .eNB_index = 0};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, required->gNB_CU_ue_id);
if (ue_context_p == NULL) {
LOG_E(RRC, "Could not find UE context for CU UE ID %d, cannot handle UE context modification request\n", required->gNB_CU_ue_id);
......@@ -2128,8 +1997,7 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p)
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
/* trigger reconfiguration */
nr_rrc_reconfiguration_req(ue_context_p, &ctxt, 0, 0);
//rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
nr_rrc_reconfiguration_req(rrc, UE, 0, 0);
return;
}
LOG_W(RRC,
......@@ -2394,7 +2262,6 @@ void *rrc_gnb_task(void *args_p) {
MessageDef *msg_p;
instance_t instance;
int result;
protocol_ctxt_t ctxt = {.module_id = 0, .enb_flag = 1, .instance = 0, .rntiMaybeUEid = 0, .frame = -1, .subframe = -1, .eNB_index = 0, .brOption = false};
long stats_timer_id = 1;
if (!IS_SOFTMODEM_NOSTATS_BIT) {
......@@ -2441,23 +2308,7 @@ void *rrc_gnb_task(void *args_p) {
/* Messages from PDCP */
/* From DU -> CU */
case F1AP_UL_RRC_MESSAGE:
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
instance,
GNB_FLAG_YES,
F1AP_UL_RRC_MESSAGE(msg_p).gNB_CU_ue_id,
0,
0);
LOG_D(NR_RRC,
"Decoding DCCH %d: ue %04lx, inst %ld, ctxt %p, size %d\n",
F1AP_UL_RRC_MESSAGE(msg_p).srb_id,
ctxt.rntiMaybeUEid,
instance,
&ctxt,
F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length);
rrc_gNB_decode_dcch(&ctxt,
F1AP_UL_RRC_MESSAGE(msg_p).srb_id,
F1AP_UL_RRC_MESSAGE(msg_p).rrc_container,
F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length);
rrc_gNB_decode_dcch(RC.nrrrc[instance], &F1AP_UL_RRC_MESSAGE(msg_p));
free(F1AP_UL_RRC_MESSAGE(msg_p).rrc_container);
break;
......@@ -2492,7 +2343,7 @@ void *rrc_gnb_task(void *args_p) {
break;
case F1AP_UE_CONTEXT_MODIFICATION_REQUIRED:
rrc_CU_process_ue_modification_required(msg_p);
rrc_CU_process_ue_modification_required(msg_p, instance);
break;
case F1AP_UE_CONTEXT_RELEASE_REQ:
......@@ -2585,53 +2436,24 @@ void *rrc_gnb_task(void *args_p) {
}
//-----------------------------------------------------------------------------
void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
void rrc_gNB_generate_SecurityModeCommand(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
//-----------------------------------------------------------------------------
{
uint8_t buffer[100];
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
AssertFatal(!ue_p->as_security_active, "logic error: security already active\n");
T(T_ENB_RRC_SECURITY_MODE_COMMAND,
T_INT(ctxt_pP->module_id),
T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe),
T_INT(ctxt_pP->rntiMaybeUEid));
T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(0), T_INT(0), T_INT(0), T_INT(ue_p->rrc_ue_id));
NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm;
int size = do_NR_SecurityModeCommand(ctxt_pP,
buffer,
rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
int size = do_NR_SecurityModeCommand(buffer,
rrc_gNB_get_next_transaction_identifier(rrc->module_id),
ue_p->ciphering_algorithm,
integrity_algorithm);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Security Mode Command\n");
LOG_I(NR_RRC, "UE %u Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rrc_ue_id, size);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
}
void
rrc_gNB_generate_UECapabilityEnquiry(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
)
//-----------------------------------------------------------------------------
{
uint8_t buffer[100];
T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rntiMaybeUEid));
gNB_RRC_UE_t *ue = &ue_context_pP->ue_context;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
ue->xids[xid] = RRC_UECAPABILITY_ENQUIRY;
int size = do_NR_SA_UECapabilityEnquiry(ctxt_pP, buffer, xid);
LOG_I(NR_RRC, "UE %d: Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d, xid %d)\n", ue->rrc_ue_id, size, xid);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
nr_rrc_transfer_protected_rrc_message(rrc, ue, DCCH, buffer, size);
}
typedef struct deliver_ue_ctxt_release_data_t {
gNB_RRC_INST *rrc;
f1ap_ue_context_release_cmd_t *release_cmd;
......@@ -2651,23 +2473,13 @@ static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_i
* Generate the RRC Connection Release to UE.
* If received, UE should switch to RRC_IDLE mode.
*/
void
rrc_gNB_generate_RRCRelease(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
)
//-----------------------------------------------------------------------------
void rrc_gNB_generate_RRCRelease(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
{
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id));
int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(rrc->module_id));
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
size);
LOG_I(NR_RRC, "UE %d: Generate RRCRelease (bytes %d)\n", UE->rrc_ue_id, size);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
const gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id);
f1ap_ue_context_release_cmd_t ue_context_release_cmd = {
......@@ -2678,7 +2490,7 @@ rrc_gNB_generate_RRCRelease(
.srb_id = DCCH,
};
deliver_ue_ctxt_release_data_t data = {.rrc = rrc, .release_cmd = &ue_context_release_cmd, .assoc_id = ue_data.du_assoc_id};
nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
nr_pdcp_data_req_srb(UE->rrc_ue_id, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_release_cmd, &data);
}
int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint32_t tmsi, uint8_t paging_drx)
......
......@@ -44,29 +44,25 @@
extern RAN_CONTEXT_t RC;
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list)
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(gNB_RRC_UE_t *ue,
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
uint8_t *inde_list)
{
if (!create_tunnel_resp_pP) {
LOG_E(NR_RRC, "create_tunnel_resp_pP error\n");
return -1;
}
LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
/* we look up by CU UE ID! Do NOT change back to RNTI! */
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
if (!ue_context_p) {
LOG_E(NR_RRC, "UE table error\n");
return -1;
}
for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
ue_context_p->ue_context.nsa_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
ue_context_p->ue_context.nsa_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
ue->nsa_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
ue->nsa_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
ue->nsa_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i];
LOG_I(RRC,
PROTOCOL_RRC_CTXT_UE_FMT " rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
"UE %d: rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp "
"addr len %d \n",
ue->rrc_ue_id,
create_tunnel_resp_pP->enb_S1u_teid[i],
ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]],
ue->nsa_gtp_teid[inde_list[i]],
inde_list[i],
i,
create_tunnel_resp_pP->eps_bearer_id[i],
......
......@@ -30,12 +30,8 @@
#ifndef RRC_GNB_GTPV1U_H_
#define RRC_GNB_GTPV1U_H_
int
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
const protocol_ctxt_t *const ctxt_pP,
int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(gNB_RRC_UE_t *ue,
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
uint8_t *inde_list
);
uint8_t *inde_list);
#endif
......@@ -93,51 +93,34 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000;
#define INTEGRITY_ALGORITHM_NONE NR_IntegrityProtAlgorithm_nia0
static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP);
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap);
/*! \fn void process_gNB_security_key (const protocol_ctxt_t* const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, uint8_t *security_key)
/*!
*\brief save security key.
*\param ctxt_pP Running context.
*\param ue_context_pP UE context.
*\param UE UE context.
*\param security_key_pP The security key received from NGAP.
*/
//------------------------------------------------------------------------------
void process_gNB_security_key (
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t *security_key_pP
)
//------------------------------------------------------------------------------
static void set_UE_security_key(gNB_RRC_UE_t *UE, uint8_t *security_key_pP)
{
char ascii_buffer[65];
uint8_t i;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
int i;
/* Saves the security key */
memcpy(UE->kgnb, security_key_pP, SECURITY_KEY_LENGTH);
memset(UE->nh, 0, SECURITY_KEY_LENGTH);
UE->nh_ncc = -1;
char ascii_buffer[65];
for (i = 0; i < 32; i++) {
sprintf(&ascii_buffer[2 * i], "%02X", UE->kgnb[i]);
}
ascii_buffer[2 * 1] = '\0';
ascii_buffer[2 * i] = '\0';
LOG_I(NR_RRC, "[gNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, UE->rnti, ascii_buffer);
LOG_I(NR_RRC, "[UE %x] Saved security key %s\n", UE->rnti, ascii_buffer);
}
//------------------------------------------------------------------------------
void
nr_rrc_pdcp_config_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const uint8_t enable_ciphering
)
//------------------------------------------------------------------------------
void nr_rrc_pdcp_config_security(gNB_RRC_UE_t *UE, bool enable_ciphering)
{
//uint8_t *k_kdf = NULL;
static int print_keys= 1;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
/* Derive the keys from kgnb */
nr_pdcp_entity_security_keys_and_algos_t security_parameters;
......@@ -157,33 +140,24 @@ nr_rrc_pdcp_config_security(
}
}
nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, DCCH, true, &security_parameters);
nr_pdcp_config_set_security(UE->rrc_ue_id, DCCH, true, &security_parameters);
}
//------------------------------------------------------------------------------
/*
* Initial UE NAS message on S1AP.
*/
void
rrc_gNB_send_NGAP_NAS_FIRST_REQ(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP,
NR_RRCSetupComplete_IEs_t *rrcSetupComplete
)
void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRCSetupComplete_IEs_t *rrcSetupComplete)
//------------------------------------------------------------------------------
{
// gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
MessageDef *message_p = NULL;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_FIRST_REQ);
MessageDef *message_p = itti_alloc_new_message(TASK_RRC_GNB, rrc->module_id, NGAP_NAS_FIRST_REQ);
ngap_nas_first_req_t *req = &NGAP_NAS_FIRST_REQ(message_p);
memset(req, 0, sizeof(*req));
req->gNB_ue_ngap_id = UE->rrc_ue_id;
/* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */
AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d) for gNB %d!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST, ctxt_pP->module_id);
AssertFatal(UE->establishment_cause < NGAP_RRC_CAUSE_LAST, "Establishment cause invalid (%jd/%d)!", UE->establishment_cause, NGAP_RRC_CAUSE_LAST);
req->establishment_cause = UE->establishment_cause;
/* Forward NAS message */
......@@ -224,8 +198,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
UE->ue_guami.amf_pointer = req->ue_identity.guami.amf_pointer;
LOG_I(NGAP,
"[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n",
ctxt_pP->module_id,
"Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n",
req->ue_identity.guami.amf_set_id,
req->ue_identity.guami.amf_region_id,
UE->rnti);
......@@ -233,7 +206,7 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
req->ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE;
}
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p);
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, message_p);
}
static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session)
......@@ -441,7 +414,6 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
{
protocol_ctxt_t ctxt = {0};
ngap_initial_context_setup_req_t *req = &NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
......@@ -457,7 +429,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p);
return (-1);
}
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
UE->amf_ue_ngap_id = req->amf_ue_ngap_id;
/* store guami in gNB_RRC_UE_t context;
......@@ -473,14 +445,6 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
// this is malloced pointers, we pass it for later free()
UE->nas_pdu = req->nas_pdu;
/* security */
rrc_gNB_process_security(&ctxt, ue_context_p, &req->security_capabilities);
process_gNB_security_key(&ctxt, ue_context_p, req->security_key);
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0);
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p);
if (req->nb_of_pdusessions > 0) {
/* if there are PDU sessions to setup, store them to be created once
* security (and UE capabilities) are received */
......@@ -491,6 +455,35 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
UE->initial_pdus[i] = req->pdusession_param[i];
}
/* security */
set_UE_security_algos(rrc, UE, &req->security_capabilities);
set_UE_security_key(UE, req->security_key);
/* TS 38.413: "store the received Security Key in the UE context and, if the
* NG-RAN node is required to activate security for the UE, take this
* security key into use.": I interpret this as "if AS security is already
* active, don't do anything" */
if (!UE->as_security_active) {
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
nr_rrc_pdcp_config_security(UE, false);
rrc_gNB_generate_SecurityModeCommand(rrc, UE);
} else {
/* if AS security key is active, we also have the UE capabilities. Then,
* there are two possibilities: we should set up PDU sessions, and/or
* forward the NAS message. */
if (req->nb_of_pdusessions > 0) {
// do not remove the above allocation which is reused here: this is used
// in handle_rrcReconfigurationComplete() to know that we need to send a
// Initial context setup response message
trigger_bearer_setup(rrc, UE, UE->n_initial_pdu, UE->initial_pdus, 0);
} else {
/* no PDU sesion to setup: acknowledge this message, and forward NAS
* message, if required */
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(rrc, UE);
rrc_forward_ue_nas_message(rrc, UE);
}
}
#ifdef E2_AGENT
signal_rrc_state_changed_to(UE, RC_SM_RRC_CONNECTED);
#endif
......@@ -498,16 +491,13 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
return 0;
}
//------------------------------------------------------------------------------
void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
//------------------------------------------------------------------------------
void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
{
MessageDef *msg_p = NULL;
int pdu_sessions_done = 0;
int pdu_sessions_failed = 0;
msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP);
msg_p = itti_alloc_new_message (TASK_RRC_ENB, rrc->module_id, NGAP_INITIAL_CONTEXT_SETUP_RESP);
ngap_initial_context_setup_resp_t *resp = &NGAP_INITIAL_CONTEXT_SETUP_RESP(msg_p);
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
......@@ -538,14 +528,11 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c
resp->nb_of_pdusessions = pdu_sessions_done;
resp->nb_of_pdusessions_failed = pdu_sessions_failed;
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
}
static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(
const protocol_ctxt_t *const ctxt_pP,
uint16_t algorithms)
static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(const gNB_RRC_INST *rrc, uint16_t algorithms)
{
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
int i;
/* preset nea0 as fallback */
int ret = 0;
......@@ -577,11 +564,8 @@ static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(
return ret;
}
static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(
const protocol_ctxt_t *const ctxt_pP,
uint16_t algorithms)
static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(const gNB_RRC_INST *rrc, uint16_t algorithms)
{
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
int i;
/* preset nia0 as fallback */
int ret = 0;
......@@ -613,58 +597,38 @@ static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(
return ret;
}
static int rrc_gNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP)
/*
* \brief set security algorithms
* \param rrc pointer to RRC context
* \param UE UE context
* \param cap security capabilities for this UE
*/
static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap)
{
bool changed = false;
NR_CipheringAlgorithm_t cipheringAlgorithm;
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
/* Save security parameters */
UE->security_capabilities = *security_capabilities_pP;
// translation
LOG_D(NR_RRC,
"[gNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n",
ctxt_pP->module_id,
UE->security_capabilities.nRencryption_algorithms,
(unsigned long)UE->ciphering_algorithm,
UE->security_capabilities.nRintegrity_algorithms,
UE->integrity_algorithm);
UE->security_capabilities = *cap;
/* Select relevant algorithms */
cipheringAlgorithm = rrc_gNB_select_ciphering(ctxt_pP, UE->security_capabilities.nRencryption_algorithms);
NR_CipheringAlgorithm_t cipheringAlgorithm = rrc_gNB_select_ciphering(rrc, cap->nRencryption_algorithms);
e_NR_IntegrityProtAlgorithm integrityProtAlgorithm = rrc_gNB_select_integrity(rrc, cap->nRintegrity_algorithms);
if (UE->ciphering_algorithm != cipheringAlgorithm) {
UE->ciphering_algorithm = cipheringAlgorithm;
changed = true;
}
integrityProtAlgorithm = rrc_gNB_select_integrity(ctxt_pP, UE->security_capabilities.nRintegrity_algorithms);
if (UE->integrity_algorithm != integrityProtAlgorithm) {
UE->integrity_algorithm = integrityProtAlgorithm;
changed = true;
}
LOG_I(NR_RRC,
"[gNB %d][UE %d] Selected security algorithms (%p): ciphering %lx, integrity %x (algorithms %s)\n",
ctxt_pP->module_id,
"[UE %d] Selected security algorithms: ciphering %lx, integrity %x\n",
UE->rrc_ue_id,
security_capabilities_pP,
cipheringAlgorithm,
integrityProtAlgorithm,
changed ? "changed" : "are the same");
return changed;
integrityProtAlgorithm);
}
//------------------------------------------------------------------------------
int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui)
//------------------------------------------------------------------------------
{
uint32_t length;
uint8_t buffer[4096];
protocol_ctxt_t ctxt = {0};
ngap_downlink_nas_t *req = &NGAP_DOWNLINK_NAS(msg_p);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_ue_ngap_id);
if (ue_context_p == NULL) {
/* Can not associate this message to an UE index, send a failure to NGAP and discard it! */
......@@ -681,71 +645,44 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
/* Create message for PDCP (DLInformationTransfer_t) */
length = do_NR_DLInformationTransfer(buffer,
sizeof(buffer),
rrc_gNB_get_next_transaction_identifier(instance),
req->nas_pdu.length,
req->nas_pdu.buffer);
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n");
/*
* switch UL or DL NAS message without RRC piggybacked to SRB2 if active.
*/
AssertFatal(!NODE_IS_DU(RC.nrrrc[ctxt.module_id]->node_type), "illegal node type DU: receiving NGAP messages at this node\n");
/* Transfer data to PDCP */
rb_id_t srb_id = UE->Srb[2].Active ? DCCH1 : DCCH;
nr_rrc_transfer_protected_rrc_message(RC.nrrrc[instance], UE, srb_id, buffer, length);
UE->nas_pdu = req->nas_pdu;
rrc_forward_ue_nas_message(rrc, UE);
return 0;
}
//------------------------------------------------------------------------------
void
rrc_gNB_send_NGAP_UPLINK_NAS(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
NR_UL_DCCH_Message_t *const ul_dcch_msg
)
//------------------------------------------------------------------------------
void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UL_DCCH_Message_t *const ul_dcch_msg)
{
MessageDef *msg_p;
NR_ULInformationTransfer_t *ulInformationTransfer = ul_dcch_msg->message.choice.c1->choice.ulInformationTransfer;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
if (ulInformationTransfer->criticalExtensions.present == NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer) {
NR_ULInformationTransfer__criticalExtensions_PR p = ulInformationTransfer->criticalExtensions.present;
if (p != NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer) {
LOG_E(NR_RRC, "UE %d: expected presence of ulInformationTransfer, but message has %d\n", UE->rrc_ue_id, p);
return;
}
NR_DedicatedNAS_Message_t *nas = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message;
uint8_t *buf = malloc(nas->size);
AssertFatal(buf != NULL, "out of memory\n");
if (!nas) {
LOG_E(NR_RRC, "UE %d: expected NAS message in ulInformation, but it is NULL\n", UE->rrc_ue_id);
return;
}
uint8_t *buf = malloc_or_fail(nas->size);
memcpy(buf, nas->buf, nas->size);
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS);
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, rrc->module_id, NGAP_UPLINK_NAS);
NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id;
NGAP_UPLINK_NAS (msg_p).nas_pdu.length = nas->size;
NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = buf;
// extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer,
// NGAP_UPLINK_NAS (msg_p).nas_pdu.length,
// ue_context_pP);
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
LOG_D(NR_RRC,"Send RRC GNB UL Information Transfer \n");
}
NGAP_UPLINK_NAS(msg_p).nas_pdu.length = nas->size;
NGAP_UPLINK_NAS(msg_p).nas_pdu.buffer = buf;
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
}
//------------------------------------------------------------------------------
void
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
)
//------------------------------------------------------------------------------
void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
{
MessageDef *msg_p;
int pdu_sessions_done = 0;
int pdu_sessions_failed = 0;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP);
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_PDUSESSION_SETUP_RESP);
ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_p);
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) {
......@@ -792,7 +729,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
if ((pdu_sessions_done > 0 || pdu_sessions_failed)) {
LOG_I(NR_RRC, "NGAP_PDUSESSION_SETUP_RESP: sending the message\n");
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
}
for(int i = 0; i < NB_RB_MAX; i++) {
......@@ -806,13 +743,11 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
{
protocol_ctxt_t ctxt={0};
ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
gNB_RRC_INST *rrc = RC.nrrrc[instance];
if (ue_context_p == NULL) {
MessageDef *msg_fail_p = NULL;
......@@ -946,18 +881,16 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
{
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt;
ngap_pdusession_modify_req_t *req = &NGAP_PDUSESSION_MODIFY_REQ(msg_p);
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_ue_ngap_id);
if (ue_context_p == NULL) {
LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_MODIFY_REQ: unknown UE from NGAP ids (%u)\n", instance, req->gNB_ue_ngap_id);
// TO implement return setup failed
return (-1);
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
bool all_failed = true;
for (int i = 0; i < req->nb_pdusessions_tomodify; i++) {
rrc_pdu_session_param_t *sess;
......@@ -992,8 +925,7 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
}
if (!all_failed) {
LOG_D(NR_RRC, "generate RRCReconfiguration \n");
rrc_gNB_modify_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
rrc_gNB_modify_dedicatedRRCReconfiguration(rrc, UE);
} else {
LOG_I(NR_RRC,
"pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n");
......@@ -1018,21 +950,13 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
return (0);
}
//------------------------------------------------------------------------------
int
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
)
//------------------------------------------------------------------------------
int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
{
MessageDef *msg_p = NULL;
uint8_t pdu_sessions_failed = 0;
uint8_t pdu_sessions_done = 0;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP);
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_PDUSESSION_MODIFY_RESP);
if (msg_p == NULL) {
LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_p is NULL \n");
return (-1);
......@@ -1099,7 +1023,7 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
if (pdu_sessions_done > 0 || pdu_sessions_failed > 0) {
LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message (total pdu session %d)\n", UE->nb_of_pdusessions);
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
} else {
itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
}
......@@ -1166,7 +1090,6 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
{
gNB_RRC_INST *rrc = RC.nrrrc[0];
uint32_t gNB_ue_ngap_id = 0;
protocol_ctxt_t ctxt;
gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id);
......@@ -1199,9 +1122,7 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
/* special case: the DU might be offline, in which case the f1_ue_data exists
* but is set to 0 */
if (cu_exists_f1_ue_data(UE->rrc_ue_id) && cu_get_f1_ue_data(UE->rrc_ue_id).du_assoc_id != 0) {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
rrc_gNB_generate_RRCRelease(rrc, UE);
/* UE will be freed after UE context release complete */
} else {
......@@ -1226,19 +1147,16 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
itti_send_msg_to_task(TASK_NGAP, instance, msg);
}
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const NR_UECapabilityInformation_t *const ue_cap_info)
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UECapabilityInformation_t *const ue_cap_info)
//------------------------------------------------------------------------------
{
NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList =
ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList;
void *buf;
NR_UERadioAccessCapabilityInformation_t rac = {0};
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
if (ueCapabilityRATContainerList->list.count == 0) {
LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti);
LOG_W(RRC, "[UE %d] bad UE capabilities\n", UE->rrc_ue_id);
}
int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf);
......@@ -1259,29 +1177,21 @@ void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
;
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_UERadioAccessCapabilityInformation, &rac);
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND);
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_UE_CAPABILITIES_IND);
ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p);
memset(ind, 0, sizeof(*ind));
ind->gNB_ue_ngap_id = UE->rrc_ue_id;
ind->ue_radio_cap.length = encoded;
ind->ue_radio_cap.buffer = buf2;
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
}
//------------------------------------------------------------------------------
void
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
)
//------------------------------------------------------------------------------
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
{
int pdu_sessions_released = 0;
MessageDef *msg_p;
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE);
msg_p = itti_alloc_new_message (TASK_RRC_GNB, rrc->module_id, NGAP_PDUSESSION_RELEASE_RESPONSE);
ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p);
memset(resp, 0, sizeof(*resp));
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
......@@ -1300,7 +1210,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
resp->nb_of_pdusessions_released = pdu_sessions_released;
resp->nb_of_pdusessions_failed = 0;
LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: rrc_ue_id %u release_pdu_sessions %d\n", resp->gNB_ue_ngap_id, pdu_sessions_released);
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p);
itti_send_msg_to_task (TASK_NGAP, rrc->module_id, msg_p);
}
//------------------------------------------------------------------------------
......@@ -1308,14 +1218,14 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
//------------------------------------------------------------------------------
{
uint32_t gNB_ue_ngap_id;
protocol_ctxt_t ctxt;
ngap_pdusession_release_command_t *cmd = &NGAP_PDUSESSION_RELEASE_COMMAND(msg_p);
gNB_ue_ngap_id = cmd->gNB_ue_ngap_id;
if (cmd->nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) {
LOG_E(NR_RRC, "incorrect number of pdu session do release %d\n", cmd->nb_pdusessions_torelease);
return -1;
}
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id);
gNB_RRC_INST *rrc = RC.nrrrc[instance];
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, gNB_ue_ngap_id);
if (!ue_context_p) {
LOG_E(NR_RRC, "[gNB %ld] not found ue context gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id);
......@@ -1324,11 +1234,10 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rrc_ue_id, 0, 0);
LOG_I(
NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu rrc_ue_id %u release_pdusessions %d \n", cmd->amf_ue_ngap_id, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease);
bool found = false;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
UE->xids[xid] = RRC_PDUSESSION_RELEASE;
for (int pdusession = 0; pdusession < cmd->nb_pdusessions_torelease; pdusession++) {
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, cmd->pdusession_release_params[pdusession].pdusession_id, false);
......@@ -1356,15 +1265,15 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
if (found) {
// TODO RRCReconfiguration To UE
LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, cmd->nas_pdu.length, cmd->nas_pdu.buffer);
rrc_gNB_generate_dedicatedRRCReconfiguration_release(rrc, UE, xid, cmd->nas_pdu.length, cmd->nas_pdu.buffer);
} else {
// gtp tunnel delete
LOG_I(NR_RRC, "gtp tunnel delete all tunnels for UE %04x\n", UE->rnti);
gtpv1u_gnb_delete_tunnel_req_t req = {0};
req.ue_id = UE->rnti;
gtpv1u_delete_ngu_tunnel(instance, &req);
gtpv1u_delete_ngu_tunnel(rrc->module_id, &req);
// NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(rrc, UE, xid);
LOG_I(NR_RRC, "Send PDU Session Release Response \n");
}
return 0;
......
......@@ -40,53 +40,25 @@
#include "NR_UL-DCCH-Message.h"
#include "NGAP_CauseRadioNetwork.h"
void
rrc_gNB_send_NGAP_NAS_FIRST_REQ(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP,
NR_RRCSetupComplete_IEs_t *rrcSetupComplete
);
void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRCSetupComplete_IEs_t *rrcSetupComplete);
int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t instance);
void
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP
);
void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mui_t *rrc_gNB_mui);
void
rrc_gNB_send_NGAP_UPLINK_NAS(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
NR_UL_DCCH_Message_t *const ul_dcch_msg
);
void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UL_DCCH_Message_t *const ul_dcch_msg);
void
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
);
void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid);
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance);
int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t instance);
int
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
);
int rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid);
void
rrc_gNB_modify_dedicatedRRCReconfiguration(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP
);
void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p);
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, const rrc_gNB_ue_context_t *const ue_context_pP, const ngap_Cause_t causeP, const long cause_valueP);
......@@ -99,25 +71,13 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
int num_pdu,
uint32_t pdu_session_id[256]);
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const NR_UECapabilityInformation_t *const ue_cap_info);
void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_UECapabilityInformation_t *const ue_cap_info);
int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance);
void
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t xid
);
void
nr_rrc_pdcp_config_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
const uint8_t send_security_mode_command
);
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid);
void nr_rrc_pdcp_config_security(gNB_RRC_UE_t *UE, bool enable_ciphering);
int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, instance_t instance);
......
......@@ -40,7 +40,7 @@
#include "uper_decoder.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "openair2/RRC/NR/rrc_gNB_GTPV1U.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "executables/softmodem-common.h"
#include "executables/nr-softmodem.h"
......@@ -282,15 +282,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
create_tunnel_req.rnti = ue_context_p->ue_context.rrc_ue_id;
create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded;
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
memset(&create_tunnel_resp, 0, sizeof(create_tunnel_resp));
if (!IS_SOFTMODEM_NOS1) {
LOG_D(RRC, "Calling gtpv1u_create_s1u_tunnel()\n");
gtpv1u_create_s1u_tunnel(ctxt.instance, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb);
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
&ctxt,
&create_tunnel_resp,
&inde_list[0]);
gtpv1u_create_s1u_tunnel(rrc->module_id, &create_tunnel_req, &create_tunnel_resp, nr_pdcp_data_req_drb);
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ue_context_p->ue_context, &create_tunnel_resp, &inde_list[0]);
}
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment