Commit 5ee44e01 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/simplify-pdu-session-management' into integration_2023_w18b

parents b2cc7505 15e85827
......@@ -111,7 +111,7 @@ f1ap_cudu_inst_t *getCxt(F1_t isCU, instance_t instanceP)
return NULL;
}
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP)
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid)
{
abort();
}
......
......@@ -263,17 +263,6 @@ typedef enum pdu_session_type_e {
PDUSessionType_unstructured = 4
}pdu_session_type_t;
typedef struct ngap_transport_layer_addr_s {
/* Length of the transport layer address buffer in bits. NGAP layer received a
* bit string<1..160> containing one of the following addresses: ipv4,
* ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but
* silently forward it to NG-U.
*/
uint8_t pdu_session_type;
uint8_t length;
uint8_t buffer[20]; // in network byte order
} ngap_transport_layer_addr_t;
typedef struct pdusession_s {
/* Unique pdusession_id for the UE. */
int pdusession_id;
......@@ -283,11 +272,16 @@ typedef struct pdusession_s {
/* Quality of service for this pdusession */
pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE];
/* The transport layer address for the IP packets */
ngap_transport_layer_addr_t upf_addr;
pdu_session_type_t pdu_session_type;
transport_layer_addr_t upf_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
/* Stores the DRB ID of the DRBs used by this PDU Session */
uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE];
uint32_t gNB_teid_N3;
transport_layer_addr_t gNB_addr_N3;
uint32_t UPF_teid_N3;
transport_layer_addr_t UPF_addr_N3;
} pdusession_t;
typedef enum pdusession_qosflow_mapping_ind_e{
......@@ -306,7 +300,8 @@ typedef struct pdusession_setup_s {
uint8_t pdusession_id;
/* The transport layer address for the IP packets */
ngap_transport_layer_addr_t gNB_addr;
uint8_t pdu_session_type;
transport_layer_addr_t gNB_addr;
/* UPF Tunnel endpoint identifier */
uint32_t gtp_teid;
......@@ -323,7 +318,8 @@ typedef struct pdusession_tobeswitched_s {
uint8_t pdusession_id;
/* The transport layer address for the IP packets */
ngap_transport_layer_addr_t upf_addr;
uint8_t pdu_session_type;
transport_layer_addr_t upf_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
......
......@@ -3808,7 +3808,6 @@ do_RRCConnectionReestablishment(
LTE_DL_CCCH_Message_t dl_ccch_msg;
LTE_RRCConnectionReestablishment_t *rrcConnectionReestablishment = NULL;
int i = 0;
ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
LTE_SRB_ToAddModList_t **SRB_configList2 = NULL;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
......
......@@ -1139,7 +1139,6 @@ int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP,
struct NR_SRB_ToAddMod *SRB2_config = NULL;
NR_DL_DCCH_Message_t dl_dcch_msg = {0};
NR_RRCReestablishment_t *rrcReestablishment = NULL;
ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
......
......@@ -179,13 +179,14 @@ static NR_SRB_ToAddModList_t **generateSRB2_confList(gNB_RRC_UE_t *ue, NR_SRB_To
return SRB_configList2;
}
static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) {
static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid)
{
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
protocol_ctxt_t ctxt = {0};
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
fill_DRB_configList(&ctxt, ue_context_p);
fill_DRB_configList(&ctxt, ue_context_p, xid);
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
// Fixme: xid not random, but almost!
......@@ -208,7 +209,7 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const
}
}
static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance) {
static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) {
instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
CU_update_UP_DL_tunnel(req, gtpInst, req->rnti);
}
......
......@@ -35,12 +35,13 @@
extern RAN_CONTEXT_t RC;
static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) {
static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid)
{
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[instance], req->rnti);
protocol_ctxt_t ctxt = {0};
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
fill_DRB_configList(&ctxt, ue_context_p);
fill_DRB_configList(&ctxt, ue_context_p, xid);
MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ);
e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p);
memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t));
......@@ -48,7 +49,8 @@ static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const r
itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p);
}
static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) {
static void cucp_cuup_bearer_context_mod_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid)
{
MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ);
e1ap_bearer_setup_req_t *req_msg = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
memcpy(req_msg, req, sizeof(*req));
......
......@@ -27,7 +27,7 @@
struct e1ap_bearer_setup_req_s;
struct e1ap_bearer_setup_resp_s;
typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance);
typedef void (*cucp_cuup_bearer_context_setup_func_t)(struct e1ap_bearer_setup_req_s *const req, instance_t instance, uint8_t xid);
struct gNB_RRC_INST_s;
void cucp_cuup_message_transfer_direct_init(struct gNB_RRC_INST_s *rrc);
......
......@@ -128,7 +128,7 @@ typedef enum UE_STATE_NR_e {
#define NO_SECURITY_MODE 0x20
/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 3
#define NR_RRC_TRANSACTION_IDENTIFIER_NUMBER 4
typedef struct {
unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
......@@ -258,14 +258,15 @@ typedef enum pdu_session_satus_e {
PDU_SESSION_STATUS_DONE,
PDU_SESSION_STATUS_ESTABLISHED,
PDU_SESSION_STATUS_REESTABLISHED, // after HO
PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA
PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA
PDU_SESSION_STATUS_FAILED,
PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE
PDU_SESSION_STATUS_TORELEASE, // to release DRB between eNB and UE
PDU_SESSION_STATUS_RELEASED
} pdu_session_status_t;
typedef struct pdu_session_param_s {
pdusession_t param;
uint8_t status;
pdu_session_status_t status;
uint8_t xid; // transaction_id
ngap_Cause_t cause;
uint8_t cause_value;
......@@ -305,6 +306,19 @@ typedef struct drb_s {
} pdcp_config;
} drb_t;
typedef enum {
RRC_FIRST_RECONF,
RRC_SETUP,
RRC_SETUP_FOR_REESTABLISHMENT,
RRC_REESTABLISH,
RRC_REESTABLISH_COMPLETE,
RRC_DEFAULT_RECONF,
RRC_DEDICATED_RECONF,
RRC_PDUSESSION_ESTABLISH,
RRC_PDUSESSION_MODIFY,
RRC_PDUSESSION_RELEASE
} rrc_action_t;
typedef struct gNB_RRC_UE_s {
uint8_t primaryCC_id;
NR_SRB_ToAddModList_t *SRB_configList;
......@@ -369,38 +383,20 @@ typedef struct gNB_RRC_UE_s {
nr_rrc_guami_t ue_guami;
ngap_security_capabilities_t security_capabilities;
/* Total number of e_rab already setup in the list */
uint8_t setup_e_rabs;
/* Number of e_rab to be setup in the list */
//NSA block
/* Number of NSA e_rab */
uint8_t nb_of_e_rabs;
/* Number of e_rab to be modified in the list */
uint8_t nb_of_modify_e_rabs;
uint8_t nb_of_failed_e_rabs;
nr_e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
/* Number of pdu session managed for the ue */
uint8_t nb_of_pdusessions;
/* Number of e_rab to be modified in the list */
uint8_t nb_of_modify_pdusessions;
uint8_t nb_of_failed_pdusessions;
rrc_pdu_session_param_t modify_pdusession[NR_NB_RB_MAX];
/* list of e_rab to be setup by RRC layers */
/* list of pdu session to be setup by RRC layers */
nr_e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION];
//release e_rabs
uint8_t nb_release_of_e_rabs;
e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB];
uint8_t nb_release_of_pdusessions;
pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION];
// LG: For GTPV1 TUNNELS
uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB];
rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB];
rb_id_t gnb_gtp_psi[S1AP_MAX_E_RAB];
//GTPV1 F1-U TUNNELS
uint32_t incoming_teid[S1AP_MAX_E_RAB];
uint32_t nsa_gtp_teid[S1AP_MAX_E_RAB];
transport_layer_addr_t nsa_gtp_addrs[S1AP_MAX_E_RAB];
rb_id_t nsa_gtp_ebi[S1AP_MAX_E_RAB];
rb_id_t nsa_gtp_psi[S1AP_MAX_E_RAB];
//SA block
int nb_of_pdusessions;
rrc_pdu_session_param_t pduSession[NGAP_MAX_PDU_SESSION];
rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
uint32_t ul_failure_timer;
uint32_t ue_release_timer;
uint32_t ue_release_timer_thres;
......@@ -412,11 +408,8 @@ typedef struct gNB_RRC_UE_s {
uint32_t ue_release_timer_thres_rrc;
uint32_t ue_reestablishment_timer;
uint32_t ue_reestablishment_timer_thres;
uint8_t e_rab_release_command_flag;
uint8_t pdu_session_release_command_flag;
uint8_t established_pdu_sessions_flag;
uint32_t ue_rrc_inactivity_timer;
int8_t reestablishment_xid;
uint8_t e_rab_release_command_flag;
uint32_t ue_rrc_inactivity_timer;
uint32_t ue_reestablishment_counter;
uint32_t ue_reconfiguration_after_reestablishment_counter;
NR_CellGroupId_t cellGroupId;
......
......@@ -164,8 +164,7 @@ void ue_cxt_mod_send_e1ap(MessageDef *msg,
void ue_cxt_mod_direct(MessageDef *msg,
instance_t instance);
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP);
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid);
void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
e1ap_bearer_setup_resp_t *e1ap_resp);
......
......@@ -106,8 +106,7 @@ extern RAN_CONTEXT_t RC;
static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn);
mui_t rrc_gNB_mui = 0;
uint8_t first_rrcreconfiguration = 0;
mui_t rrc_gNB_mui = 0;
///---------------------------------------------------------------------------------------------------------------///
///---------------------------------------------------------------------------------------------------------------///
......@@ -349,7 +348,9 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance,
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
gNB_RRC_INST *rrc = RC.nrrrc[instance];
unsigned char buf[1024];
int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(instance), masterCellGroup, masterCellGroup_len, &rrc->configuration);
uint8_t xid = rrc_gNB_get_next_transaction_identifier(instance);
ue_p->xids[xid] = RRC_SETUP;
int size = do_RRCSetup(ue_context_pP, buf, xid, masterCellGroup, masterCellGroup_len, &rrc->configuration);
AssertFatal(size > 0, "do_RRCSetup failed\n");
AssertFatal(size <= 1024, "memory corruption\n");
......@@ -376,7 +377,7 @@ static void rrc_gNB_generate_RRCSetup(instance_t instance,
}
//-----------------------------------------------------------------------------
static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id)
static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t module_id, rnti_t rnti, const int CC_id)
//-----------------------------------------------------------------------------
{
LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n");
......@@ -387,7 +388,9 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
unsigned char buf[1024];
int size = do_RRCSetup(ue_context_pP, buf, rrc_gNB_get_next_transaction_identifier(module_id), NULL, 0, &rrc_instance_p->configuration);
uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id);
ue_p->xids[xid] = RRC_SETUP_FOR_REESTABLISHMENT;
int size = do_RRCSetup(ue_context_pP, buf, xid, NULL, 0, &rrc_instance_p->configuration);
AssertFatal(size > 0, "do_RRCSetup failed\n");
AssertFatal(size <= 1024, "memory corruption\n");
......@@ -433,6 +436,7 @@ static void rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t
.srb_id = CCCH
};
rrc_instance_p->mac_rrc.dl_rrc_message_transfer(module_id, &dl_rrc);
return xid;
}
static void rrc_gNB_generate_RRCReject(module_id_t module_id, rrc_gNB_ue_context_t *const ue_context_pP)
......@@ -492,11 +496,10 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
//-----------------------------------------------------------------------------
{
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
/******************** Radio Bearer Config ********************/
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
AssertFatal(ue_p->nb_of_pdusessions == 0, "logic bug: PDU sessions present before RRC Connection established\n");
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
ue_p->xids[xid] = RRC_DEFAULT_RECONF;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
......@@ -583,9 +586,8 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
}
}
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *ue_context_pP) {
void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, uint8_t xid)
{
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
int qos_flow_index = 0;
......@@ -594,8 +596,6 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
uint8_t nb_drb_to_setup = rrc->configuration.drbs;
long drb_priority[NGAP_MAX_DRBS_PER_UE];
int xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
if (!ue_p->DRB_configList)
ue_p->DRB_configList = CALLOC(1, sizeof(*ue_p->DRB_configList));
else
......@@ -780,58 +780,53 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
rrc_gNB_ue_context_t *ue_context_pP)
//-----------------------------------------------------------------------------
{
NR_DRB_ToAddMod_t *DRB_config = NULL;
NR_DRB_ToAddModList_t **DRB_configList = NULL;
NR_DRB_ToAddMod_t *DRB_config = NULL;
NR_DRB_ToAddModList_t *DRB_configList2 = NULL;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*dedicatedNAS_MessageList = NULL;
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
int qos_flow_index = 0;
int i, j;
int qos_flow_index = 0;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
DRB_configList = &ue_p->DRB_configList;
ue_p->xids[xid] = RRC_DEDICATED_RECONF;
DRB_configList2 = CALLOC(1, sizeof(NR_DRB_ToAddModList_t));
memset(DRB_configList2, 0, sizeof(NR_DRB_ToAddModList_t));
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) {
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
// bypass the new and already configured pdu sessions
if (ue_p->modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) {
ue_p->modify_pdusession[i].xid = xid;
if (ue_p->pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
ue_p->pduSession[i].xid = xid;
continue;
}
if (ue_p->modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) {
if (ue_p->pduSession[i].cause != NGAP_CAUSE_NOTHING) {
// set xid of failure pdu session
ue_p->modify_pdusession[i].xid = xid;
ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED;
ue_p->pduSession[i].xid = xid;
ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED;
continue;
}
// search exist DRB_config
for (j = 0; j < (*DRB_configList)->list.count; j++) {
if ((*DRB_configList)->list.array[j]->cnAssociation->choice.sdap_Config->pdu_Session == ue_p->modify_pdusession[i].param.pdusession_id) {
DRB_config = (*DRB_configList)->list.array[j];
int j;
for (j = 0; i < NGAP_MAX_DRBS_PER_UE; j++) {
if (ue_p->established_drbs[j].status != DRB_INACTIVE
&& ue_p->established_drbs[j].cnAssociation.sdap_config.pdusession_id == ue_p->pduSession[i].param.pdusession_id)
break;
}
}
if (DRB_config == NULL) {
ue_p->modify_pdusession[i].xid = xid;
ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED;
ue_p->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_p->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unspecified;
ue_p->nb_of_failed_pdusessions++;
if (j == NGAP_MAX_DRBS_PER_UE) {
ue_p->pduSession[i].xid = xid;
ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED;
ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_unspecified;
continue;
}
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
for (qos_flow_index = 0; qos_flow_index < ue_p->modify_pdusession[i].param.nb_qos; qos_flow_index++) {
switch (ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI) {
for (qos_flow_index = 0; qos_flow_index < ue_p->pduSession[i].param.nb_qos; qos_flow_index++) {
switch (ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI) {
case 1: //100ms
case 2: //150ms
case 3: //50ms
......@@ -845,12 +840,11 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
break;
default:
LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI);
ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED;
ue_p->modify_pdusession[i].xid = xid;
ue_p->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_p->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value;
ue_p->nb_of_failed_pdusessions++;
LOG_E(NR_RRC, "not supported 5qi %lu\n", ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI);
ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED;
ue_p->pduSession[i].xid = xid;
ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_p->pduSession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value;
continue;
}
......@@ -860,24 +854,20 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
DRB_config->drb_Identity,
i,
qos_flow_index,
ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI);
ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI);
}
asn1cSeqAdd(&DRB_configList2->list, DRB_config);
ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_DONE;
ue_p->modify_pdusession[i].xid = xid;
if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) {
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->modify_pdusession[i].param.nas_pdu.buffer, ue_p->modify_pdusession[i].param.nas_pdu.length);
asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
ue_p->pduSession[i].xid = xid;
LOG_I(NR_RRC, "add NAS info with size %d (pdusession id %d)\n", ue_p->pduSession[i].param.nas_pdu.length, ue_p->modify_pdusession[i].param.pdusession_id);
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
asn1cSequenceAdd(dedicatedNAS_MessageList->list,NR_DedicatedNAS_Message_t, dedicatedNAS_Message);
OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length);
LOG_I(NR_RRC, "add NAS info with size %d (pdusession id %d)\n", ue_p->pduSession[i].param.nas_pdu.length, ue_p->pduSession[i].param.pdusession_id);
} else {
// TODO
LOG_E(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->modify_pdusession[i].param.pdusession_id);
LOG_W(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->pduSession[i].param.pdusession_id);
}
}
......@@ -907,11 +897,11 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
/* Free all NAS PDUs */
for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) {
if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) {
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
/* Free the NAS PDU buffer and invalidate it */
free(ue_p->modify_pdusession[i].param.nas_pdu.buffer);
ue_p->modify_pdusession[i].param.nas_pdu.buffer = NULL;
free(ue_p->pduSession[i].param.nas_pdu.buffer);
ue_p->pduSession[i].param.nas_pdu.buffer = NULL;
}
}
......@@ -986,14 +976,24 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
}
uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ctxt_pP, buffer, RRC_BUF_SIZE, xid, NULL, NULL, *DRB_Release_configList2, NULL, NULL, NULL, dedicatedNAS_MessageList, NULL, NULL, NULL, NULL, NULL);
ue_p->pdu_session_release_command_flag = 1;
int size = do_RRCReconfiguration(ctxt_pP,
buffer,
RRC_BUF_SIZE,
xid,
NULL,
NULL,
*DRB_Release_configList2,
NULL,
NULL,
NULL,
dedicatedNAS_MessageList,
NULL,
NULL,
NULL,
NULL,
NULL);
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
ue_p->pdu_session_release_command_flag = 1;
/* Free all NAS PDUs */
if (nas_length > 0) {
/* Free the NAS PDU buffer and invalidate it */
......@@ -1207,16 +1207,18 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
SRB_configList = &(ue_p->SRB_configList);
uint8_t buffer[RRC_BUF_SIZE] = {0};
uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id);
ue_p->xids[xid] = RRC_REESTABLISH;
int size = do_RRCReestablishment(ctxt_pP,
ue_context_pP,
CC_id,
buffer,
RRC_BUF_SIZE,
rrc_gNB_get_next_transaction_identifier(module_id),
SRB_configList,
masterCellGroup_from_DU,
scc,
&rrc->carrier);
ue_context_pP,
CC_id,
buffer,
RRC_BUF_SIZE,
xid,
SRB_configList,
masterCellGroup_from_DU,
scc,
&rrc->carrier);
LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size);
......@@ -1462,10 +1464,9 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
int i = 0;
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE;
ue_p->StatusRrc = NR_RRC_CONNECTED;
ue_p->ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
ue_p->reestablishment_xid = new_xid;
RRCReestablishmentComplete_fill_SRB2_configList(ctxt_pP, ue_context_pP, xid, new_xid);
RRCReestablishmentComplete_fill_DRB_configList(ctxt_pP, ue_context_pP, new_xid);
RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti);
......@@ -1751,14 +1752,14 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
((cause == NR_ReestablishmentCause_otherFailure) ? "Other Failure"
: (cause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure"
: "reconfigurationFailure"));
uint8_t xid = -1;
if (physCellId != gnb_rrc_inst->carrier.physCellId) {
/* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was received in this cell */
LOG_E(NR_RRC,
" NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n",
physCellId,
gnb_rrc_inst->carrier.physCellId);
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0);
xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0);
break;
}
......@@ -1772,7 +1773,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0x1 || rrcReestablishmentRequest.ue_Identity.c_RNTI > 0xffef) {
/* c_RNTI range error should not happen */
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n");
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0);
xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0);
break;
}
......@@ -1782,7 +1783,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if (ue_context_p == NULL) {
LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n");
rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0);
xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0);
break;
}
// c-plane not end
......@@ -1797,7 +1798,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
UE->StatusRrc = NR_RRC_RECONFIGURED;
protocol_ctxt_t ctxt_old_p;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, module_id, GNB_FLAG_YES, c_rnti, 0, 0);
rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, UE->reestablishment_xid);
rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, ue_context_p, xid);
for (uint8_t pdusessionid = 0; pdusessionid < UE->nb_of_pdusessions; pdusessionid++) {
if (UE->pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) {
......@@ -1814,8 +1815,6 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, rnti_t rnti, const uint
UE->ue_reestablishment_timer = 0;
// UE->ue_release_timer_s1 = 0;
UE->ue_release_timer_rrc = 0;
UE->reestablishment_xid = -1;
// Insert C-RNTI to map
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i];
......@@ -1899,21 +1898,259 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context,
asn1cCallocOne(ue_ctxt->measResults, measurementReport->criticalExtensions.choice.measurementReport->measResults);
}
static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP,
const NR_RRCReestablishmentComplete_t *reestablishment_complete)
{
rnti_t reestablish_rnti = 0;
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
rrc_gNB_ue_context_t *ue_context_p = NULL;
gNB_RRC_UE_t *UE = NULL;
// Select C-RNTI from map
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i];
LOG_I(NR_RRC,
"nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n",
i,
nr_reestablish_rnti_map->ue_id,
nr_reestablish_rnti_map->c_rnti,
ctxt_pP->rntiMaybeUEid);
if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
LOG_I(NR_RRC,
"Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n",
i,
nr_reestablish_rnti_map->ue_id,
nr_reestablish_rnti_map->c_rnti);
reestablish_rnti = nr_reestablish_rnti_map->c_rnti;
ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti);
UE = &ue_context_p->ue_context;
break;
}
}
if (ue_context_p == NULL || UE == NULL) {
LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n");
return -1;
}
DevAssert(reestablishment_complete->criticalExtensions.present
== NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete);
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP,
reestablish_rnti,
ue_context_p,
reestablishment_complete->rrc_TransactionIdentifier);
nr_rrc_mac_remove_ue(reestablish_rnti);
UE->ue_reestablishment_counter++;
// UE->ue_release_timer = 0;
UE->ue_reestablishment_timer = 1;
// remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered
UE->ue_reestablishment_timer_thres = 1000;
return 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)
{
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;
LOG_I(NR_RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid);
int eutra_index = -1;
if (ue_cap_info->criticalExtensions.present == NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation) {
const NR_UE_CapabilityRAT_ContainerList_t *ue_CapabilityRAT_ContainerList =
ue_cap_info->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList;
for (int i = 0; i < ue_CapabilityRAT_ContainerList->list.count; i++) {
const NR_UE_CapabilityRAT_Container_t *ue_cap_container = ue_CapabilityRAT_ContainerList->list.array[i];
if (ue_cap_container->rat_Type == NR_RAT_Type_nr) {
if (UE->UE_Capability_nr) {
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
UE->UE_Capability_nr = 0;
}
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_NR_Capability,
(void **)&UE->UE_Capability_nr,
ue_cap_container->ue_CapabilityRAT_Container.buf,
ue_cap_container->ue_CapabilityRAT_Container.size,
0,
0);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
}
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);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
UE->UE_Capability_nr = 0;
}
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);
}
eutra_index = i;
}
if (ue_cap_container->rat_Type == NR_RAT_Type_eutra_nr) {
if (UE->UE_Capability_MRDC) {
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
UE->UE_Capability_MRDC = 0;
}
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_MRDC_Capability,
(void **)&UE->UE_Capability_MRDC,
ue_cap_container->ue_CapabilityRAT_Container.buf,
ue_cap_container->ue_CapabilityRAT_Container.size,
0,
0);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
}
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);
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
UE->UE_Capability_MRDC = 0;
}
UE->UE_MRDC_Capability_size = ue_cap_container->ue_CapabilityRAT_Container.size;
}
if (ue_cap_container->rat_Type == NR_RAT_Type_eutra) {
// TODO
}
}
if (eutra_index == -1)
return -1;
}
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ue_cap_info);
}
// we send the UE capabilities request before RRC connection is complete,
// so we cannot have a PDU session yet
AssertFatal(UE->nb_of_pdusessions == 0, "logic bug: received capabilities while PDU session established\n");
// TODO: send UE context modification response with UE capabilities to
// allow DU configure CellGroupConfig
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
return 0;
}
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)
{
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;
NR_RRCSetupComplete_IEs_t *setup_complete_ies = setup_complete->criticalExtensions.choice.rrcSetupComplete;
if (setup_complete_ies->ng_5G_S_TMSI_Value != NULL) {
if (setup_complete_ies->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) {
if (setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) {
LOG_E(NR_RRC,
"wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu",
(long unsigned int)
setup_complete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size);
return -1;
}
if (UE->ng_5G_S_TMSI_Part1 != 0) {
UE->ng_5G_S_TMSI_Part2 = BIT_STRING_to_uint16(&setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2);
}
/* TODO */
} else if (setup_complete_ies->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) {
if (setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) {
LOG_E(NR_RRC,
"wrong ng_5G_S_TMSI size, expected 6, provided %lu",
(long unsigned int)setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size);
return -1;
}
uint64_t fiveg_s_TMSI = bitStr_to_uint64(&setup_complete_ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI);
LOG_I(NR_RRC,
"Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n",
fiveg_s_TMSI,
fiveg_s_TMSI >> 38,
fiveg_s_TMSI >> 38,
(fiveg_s_TMSI >> 32) & 0x3F,
(fiveg_s_TMSI >> 32) & 0x3F,
(uint32_t)fiveg_s_TMSI);
if (UE->Initialue_identity_5g_s_TMSI.presence) {
UE->Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38;
UE->Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F;
UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI;
}
}
}
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));
UE->ue_release_timer = 0;
return 0;
}
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)
{
LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %lx\n", ctxt_pP->rntiMaybeUEid);
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;
rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid);
if (get_softmodem_params()->sa) {
switch (UE->xids[xid]) {
case RRC_PDUSESSION_RELEASE: {
gtpv1u_gnb_delete_tunnel_req_t req = {0};
gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req);
// NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
} break;
case RRC_PDUSESSION_ESTABLISH:
if (UE->nb_of_pdusessions > 0)
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, xid);
break;
case RRC_PDUSESSION_MODIFY:
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, ue_context_p, xid);
break;
case RRC_FIRST_RECONF:
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
break;
default:
LOG_E(RRC, "Received unexpected xid: %d\n", xid);
}
}
}
//-----------------------------------------------------------------------------
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
)
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)
//-----------------------------------------------------------------------------
{
asn_dec_rval_t dec_rval;
NR_UL_DCCH_Message_t *ul_dcch_msg = NULL;
uint8_t xid;
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
int i;
if ((Srb_id != 1) && (Srb_id != 2)) {
LOG_E(NR_RRC, "Received message on SRB%ld, should not have ...\n", Srb_id);
......@@ -1922,38 +2159,27 @@ rrc_gNB_decode_dcch(
}
LOG_D(NR_RRC, "Decoding UL-DCCH Message\n");
//for (int i=0;i<sdu_sizeP;i++) printf("%02x ",Rx_sdu[i]);
//printf("\n");
dec_rval = uper_decode(
NULL,
&asn_DEF_NR_UL_DCCH_Message,
(void **)&ul_dcch_msg,
Rx_sdu,
sdu_sizeP,
0,
0);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
{
for (i = 0; i < sdu_sizeP; i++) {
for (int i = 0; i < sdu_sizeP; i++) {
LOG_T(NR_RRC, "%x.", Rx_sdu[i]);
}
LOG_T(NR_RRC, "\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);
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);
return -1;
}
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) {
switch (ul_dcch_msg->message.choice.c1->present) {
......@@ -1962,148 +2188,12 @@ rrc_gNB_decode_dcch(
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete:
LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %lx\n", ctxt_pP->rntiMaybeUEid);
if(!ue_context_p) {
LOG_E(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
break;
}
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(Rx_sdu), sdu_sizeP,
"[MSG] RRC Connection Reconfiguration Complete\n");
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(RRCReconfigurationComplete) ---> RRC_gNB]\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH,
sdu_sizeP);
if (ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete) {
if (ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->criticalExtensions.present ==
NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete)
rrc_gNB_process_RRCReconfigurationComplete(
ctxt_pP,
ue_context_p,
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
}
if (get_softmodem_params()->sa) {
if (UE->pdu_session_release_command_flag == 1) {
xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier;
UE->pdu_session_release_command_flag = 0;
//gtp tunnel delete
gtpv1u_gnb_delete_tunnel_req_t req={0};
for(i = 0; i < NB_RB_MAX; i++) {
if (xid == UE->pduSession[i].xid) {
req.pdusession_id[req.num_pdusession++] = UE->gnb_gtp_psi[i];
UE->gnb_gtp_teid[i] = 0;
memset(&UE->gnb_gtp_addrs[i], 0, sizeof(UE->gnb_gtp_addrs[i]));
UE->gnb_gtp_psi[i] = 0;
}
}
gtpv1u_delete_ngu_tunnel(ctxt_pP->instance, &req);
//NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid);
} else if (UE->established_pdu_sessions_flag != 1) {
if (UE->reestablishment_xid < 0) {
if (UE->nb_of_pdusessions > 0) {
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
}
} else {
UE->reestablishment_xid = -1;
}
}
if (UE->nb_of_modify_pdusessions > 0) {
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP,
ue_context_p,
ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier);
UE->nb_of_modify_pdusessions = 0;
UE->nb_of_failed_pdusessions = 0;
memset(UE->modify_pdusession, 0, sizeof(UE->modify_pdusession));
for(int i = 0; i < NR_NB_RB_MAX; i++) {
UE->modify_pdusession[i].xid = -1;
}
}
}
if (first_rrcreconfiguration == 0){
first_rrcreconfiguration = 1;
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p);
}
handle_rrcReconfigurationComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete);
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete:
if(!ue_context_p) {
LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
break;
}
LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
"[MSG] RRC SetupComplete\n");
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(RRCSetupComplete) ---> RRC_gNB\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH,
sdu_sizeP);
if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.present ==
NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) {
if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.
rrcSetupComplete->ng_5G_S_TMSI_Value != NULL) {
if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.
rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) {
// ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9))
if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.
rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) {
LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu",
(long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->
criticalExtensions.choice.rrcSetupComplete->
ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size);
return -1;
}
if (UE->ng_5G_S_TMSI_Part1 != 0) {
UE->ng_5G_S_TMSI_Part2 =
BIT_STRING_to_uint16(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2);
}
/* TODO */
} else if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.
rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) {
// NG-5G-S-TMSI ::= BIT STRING (SIZE (48))
if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.
rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) {
LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu",
(long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->
criticalExtensions.choice.rrcSetupComplete->
ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size);
return -1;
}
uint64_t fiveg_s_TMSI = bitStr_to_uint64(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->
criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI);
LOG_I(NR_RRC, "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n",
fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38,
(fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F,
(uint32_t)fiveg_s_TMSI);
if (UE->Initialue_identity_5g_s_TMSI.presence == true) {
UE->Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38;
UE->Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F;
UE->Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI;
}
}
}
rrc_gNB_process_RRCSetupComplete(
ctxt_pP,
ue_context_p,
ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->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));
}
UE->ue_release_timer = 0;
if (handle_rrcSetupComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete) == -1)
return -1;
break;
case NR_UL_DCCH_MessageType__c1_PR_measurementReport:
......@@ -2114,43 +2204,41 @@ rrc_gNB_decode_dcch(
rrc_gNB_process_MeasurementReport(ue_context_p, ul_dcch_msg->message.choice.c1->choice.measurementReport);
break;
case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
LOG_I(NR_RRC,"Recived RRC GNB UL Information Transfer \n");
if(!ue_context_p) {
LOG_I(NR_RRC, "Processing ulInformationTransfer UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
break;
}
case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
LOG_I(NR_RRC, "Recived RRC GNB UL Information Transfer \n");
if (!ue_context_p) {
LOG_I(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");
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");
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP,
ue_context_p,
ul_dcch_msg);
}
break;
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, ue_context_p, ul_dcch_msg);
}
break;
case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete:
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;
}
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_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 "
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) ) {
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
......@@ -2159,178 +2247,35 @@ rrc_gNB_decode_dcch(
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
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_W(NR_RRC,
PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(securityModeFailure) ---> RRC_gNB\n",
PROTOCOL_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);
}
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
break;
case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
if(!ue_context_p) {
LOG_I(NR_RRC, "Processing ueCapabilityInformation UE %lx, ue_context_p is NULL\n", ctxt_pP->rntiMaybeUEid);
break;
}
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP,
"[MSG] NR_RRC UECapablility Information\n");
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH);
LOG_D(RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(UECapabilityInformation) ---> 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);
}
LOG_I(NR_RRC, "got UE capabilities for UE %lx\n", ctxt_pP->rntiMaybeUEid);
int eutra_index = -1;
if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present ==
NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) {
for(i = 0;i < ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count; i++){
if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
NR_RAT_Type_nr){
if (UE->UE_Capability_nr) {
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
UE->UE_Capability_nr = 0;
}
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_NR_Capability,
(void **)&UE->UE_Capability_nr,
ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]
->ue_CapabilityRAT_Container.buf,
ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]
->ue_CapabilityRAT_Container.size,
0,
0);
if(LOG_DEBUGFLAG(DEBUG_ASN1)){
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
}
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);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
UE->UE_Capability_nr = 0;
}
UE->UE_Capability_size = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]
->ue_CapabilityRAT_Container.size;
if(eutra_index != -1){
LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n");
exit(1);
}
eutra_index = i;
}
if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
NR_RAT_Type_eutra_nr){
if (UE->UE_Capability_MRDC) {
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
UE->UE_Capability_MRDC = 0;
}
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_MRDC_Capability,
(void **)&UE->UE_Capability_MRDC,
ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]
->ue_CapabilityRAT_Container.buf,
ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]
->ue_CapabilityRAT_Container.size,
0,
0);
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
}
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);
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
UE->UE_Capability_MRDC = 0;
}
UE->UE_MRDC_Capability_size =
ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]
->ue_CapabilityRAT_Container.size;
}
if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type ==
NR_RAT_Type_eutra){
//TODO
}
}
if(eutra_index == -1)
break;
}
if (get_softmodem_params()->sa) {
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP,
ue_context_p,
ul_dcch_msg);
}
// we send the UE capabilities request before RRC connection is complete,
// so we cannot have a PDU session yet
AssertFatal(UE->established_pdu_sessions_flag == 0, "logic bug: received capabilities while PDU session established\n");
// TODO: send UE context modification response with UE capabilities to
// allow DU configure CellGroupConfig
rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p);
break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: {
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)Rx_sdu, sdu_sizeP, "[MSG] NR_RRC Connection Reestablishment Complete\n");
LOG_I(NR_RRC, "RLC RB %02d --- RLC_DATA_IND %d bytes (rrcReestablishmentComplete) ---> RRC_gNB\n", DCCH, sdu_sizeP);
rnti_t reestablish_rnti = 0;
// Select C-RNTI from map
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i];
LOG_I(NR_RRC, "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti, ctxt_pP->rntiMaybeUEid);
if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) {
LOG_I(NR_RRC, "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti);
reestablish_rnti = nr_reestablish_rnti_map->c_rnti;
ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti);
UE = &ue_context_p->ue_context;
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_W(NR_RRC,
PROTOCOL_RRC_CTXT_UE_FMT
" RLC RB %02d --- RLC_DATA_IND %d bytes "
"(securityModeFailure) ---> RRC_gNB\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
DCCH,
sdu_sizeP);
if (!ue_context_p) {
LOG_E(NR_RRC, "NR_RRCReestablishmentComplete without UE context, fault\n");
break;
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg);
}
if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) {
rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->rrc_TransactionIdentifier);
nr_rrc_mac_remove_ue(reestablish_rnti);
rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p);
break;
UE->ue_reestablishment_counter++;
}
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;
break;
// UE->ue_release_timer = 0;
UE->ue_reestablishment_timer = 1;
// remove UE after 100 frames after NR_RRCReestablishmentRelease is triggered
UE->ue_reestablishment_timer_thres = 1000;
} break;
case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete:
if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete)
== -1)
return -1;
break;
default:
break;
......@@ -2663,7 +2608,8 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
}
// send the F1 response message up to update F1-U tunnel info
rrc->cucp_cuup.bearer_context_mod(&req, instance);
// it seems the rrc transaction id (xid) is not needed here
rrc->cucp_cuup.bearer_context_mod(&req, instance, 0);
NR_CellGroupConfig_t *cellGroupConfig = NULL;
......
......@@ -58,14 +58,14 @@ int rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_
return -1;
}
for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i];
ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[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];
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),
create_tunnel_resp_pP->enb_S1u_teid[i],
ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]],
ue_context_p->ue_context.nsa_gtp_teid[inde_list[i]],
inde_list[i],
i,
create_tunnel_resp_pP->eps_bearer_id[i],
......@@ -90,14 +90,14 @@ int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ct
}
for (int i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
ue_context_p->ue_context.gnb_gtp_teid[i + offset] = create_tunnel_resp_pP->gnb_NGu_teid[i];
ue_context_p->ue_context.gnb_gtp_addrs[i + offset] = create_tunnel_resp_pP->gnb_addr;
ue_context_p->ue_context.gnb_gtp_psi[i + offset] = create_tunnel_resp_pP->pdusession_id[i];
ue_context_p->ue_context.pduSession[i + offset].param.gNB_teid_N3 = create_tunnel_resp_pP->gnb_NGu_teid[i];
ue_context_p->ue_context.pduSession[i + offset].param.gNB_addr_N3 = create_tunnel_resp_pP->gnb_addr;
AssertFatal(ue_context_p->ue_context.pduSession[i + offset].param.pdusession_id == create_tunnel_resp_pP->pdusession_id[i], "");
LOG_I(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT " nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, id %u, gtp addr len %d \n",
PROTOCOL_NR_RRC_CTXT_UE_FMT
" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u) bearer UE context index %u, id %u, gtp addr len %d \n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
create_tunnel_resp_pP->gnb_NGu_teid[i],
ue_context_p->ue_context.gnb_gtp_teid[i + offset],
i,
create_tunnel_resp_pP->pdusession_id[i],
create_tunnel_resp_pP->gnb_addr.length);
......
......@@ -319,7 +319,8 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
/* mandatory PDUSessionType */
case NGAP_ProtocolIE_ID_id_PDUSessionType:
session->upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType;
session->pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType;
AssertFatal(session->pdu_session_type == PDUSessionType_ipv4, "To be developped: support not IPv4 sessions\n");
break;
/* optional SecurityIndication */
......@@ -405,7 +406,6 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
}
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0);
UE->established_pdu_sessions_flag = 1;
}
/* NAS PDU */
......@@ -448,9 +448,11 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c
if (session->status == PDU_SESSION_STATUS_DONE) {
pdu_sessions_done++;
resp->pdusessions[pdusession].pdusession_id = session->param.pdusession_id;
resp->pdusessions[pdusession].gtp_teid = UE->gnb_gtp_teid[pdusession];
memcpy(resp->pdusessions[pdusession].gNB_addr.buffer, UE->gnb_gtp_addrs[pdusession].buffer, 20);
resp->pdusessions[pdusession].gNB_addr.length = 4;
resp->pdusessions[pdusession].gtp_teid = session->param.gNB_teid_N3;
memcpy(resp->pdusessions[pdusession].gNB_addr.buffer,
session->param.gNB_addr_N3.buffer,
sizeof(resp->pdusessions[pdusession].gNB_addr.buffer));
resp->pdusessions[pdusession].gNB_addr.length = 4; // Fixme: IPv4 hard coded here
resp->pdusessions[pdusession].nb_of_qos_flow = session->param.nb_qos;
for (int qos_flow_index = 0; qos_flow_index < session->param.nb_qos; qos_flow_index++) {
resp->pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi;
......@@ -679,10 +681,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
pdusession_setup_t *tmp = &resp->pdusessions[pdu_sessions_done];
tmp->pdusession_id = session->param.pdusession_id;
tmp->nb_of_qos_flow = session->param.nb_qos;
tmp->gtp_teid = UE->gnb_gtp_teid[pdusession];
tmp->gNB_addr.pdu_session_type = PDUSessionType_ipv4;
tmp->gNB_addr.length = UE->gnb_gtp_addrs[pdusession].length;
memcpy(tmp->gNB_addr.buffer, UE->gnb_gtp_addrs[pdusession].buffer, tmp->gNB_addr.length);
tmp->gtp_teid = session->param.gNB_teid_N3;
tmp->pdu_session_type = session->param.pdu_session_type; // FixMe: IPv4 hardcoded here
tmp->gNB_addr.length = session->param.gNB_addr_N3.length;
memcpy(tmp->gNB_addr.buffer, session->param.gNB_addr_N3.buffer, tmp->gNB_addr.length);
for (int qos_flow_index = 0; qos_flow_index < tmp->nb_of_qos_flow; qos_flow_index++) {
tmp->associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi;
tmp->associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
......@@ -729,15 +731,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
{
gNB_RRC_INST *rrc;
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt={0};
ngap_pdusession_setup_req_t* msg=&NGAP_PDUSESSION_SETUP_REQ(msg_p);
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], msg->gNB_ue_ngap_id);
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);
rrc = RC.nrrrc[ctxt.module_id];
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id);
if (ue_context_p == NULL) {
......@@ -759,6 +759,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
pdusession_t *session = &pduSession->param;
LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions);
session->pdusession_id = msg->pdusession_setup_params[i].pdusession_id;
session->pdu_session_type = msg->pdusession_setup_params[i].pdu_session_type;
session->nas_pdu = msg->pdusession_setup_params[i].nas_pdu;
session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer;
decodePDUSessionResourceSetup(session);
......@@ -818,7 +819,9 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
}
}
}
rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance);
int xid = rrc_gNB_get_next_transaction_identifier(instance);
UE->xids[xid] = RRC_PDUSESSION_ESTABLISH;
rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance, xid);
return;
}
......@@ -929,50 +932,46 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
ctxt.eNB_index = 0;
uint8_t nb_of_failed_pdusessions = 0;
bool all_failed = true;
for (int i = 0; i < req->nb_pdusessions_tomodify; i++) {
int j;
for (j = 0; j < UE->nb_of_pdusessions; j++)
if (UE->modify_pdusession[j].param.pdusession_id == req->pdusession_modify_params[j].pdusession_id)
rrc_pdu_session_param_t *sess;
const pdusession_t *sessMod = req->pdusession_modify_params + i;
for (sess = UE->pduSession; sess < UE->pduSession + UE->nb_of_pdusessions; sess++)
if (sess->param.pdusession_id == sessMod->pdusession_id)
break;
if (j == UE->nb_of_pdusessions) {
LOG_W(NR_RRC, "To finish, modify a not existing pdu session\n");
// handle multiple pdu session id
LOG_D(NR_RRC, "handle multiple pdu session id \n");
UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW;
UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[j].pdusession_id;
UE->modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
nb_of_failed_pdusessions++;
if (sess == UE->pduSession + UE->nb_of_pdusessions) {
LOG_W(NR_RRC, "Requested modification of non-existing PDU session, refusing modification\n");
UE->nb_of_pdusessions++;
sess->status = PDU_SESSION_STATUS_FAILED;
sess->param.pdusession_id = sessMod->pdusession_id;
sess->cause = NGAP_CAUSE_RADIO_NETWORK;
UE->pduSession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
} else {
UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW;
UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id;
UE->modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->modify_pdusession[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances;
UE->modify_pdusession[j].status = PDU_SESSION_STATUS_NEW;
UE->modify_pdusession[j].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id;
UE->modify_pdusession[j].cause = NGAP_CAUSE_NOTHING;
if (req->pdusession_modify_params[i].nas_pdu.buffer != NULL) {
UE->modify_pdusession[i].param.nas_pdu = req->pdusession_modify_params[i].nas_pdu;
all_failed = false;
sess->status = PDU_SESSION_STATUS_NEW;
sess->param.pdusession_id = sessMod->pdusession_id;
sess->cause = NGAP_CAUSE_RADIO_NETWORK;
sess->cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances;
sess->status = PDU_SESSION_STATUS_NEW;
sess->param.pdusession_id = sessMod->pdusession_id;
sess->cause = NGAP_CAUSE_NOTHING;
if (sessMod->nas_pdu.buffer != NULL) {
UE->pduSession[i].param.nas_pdu = sessMod->nas_pdu;
}
// Save new pdu session parameters, qos, upf addr, teid
decodePDUSessionResourceModify(&UE->modify_pdusession[j].param, UE->modify_pdusession[i].param.pdusessionTransfer);
UE->modify_pdusession[j].param.upf_addr = UE->pduSession[j].param.upf_addr;
UE->modify_pdusession[j].param.gtp_teid = UE->pduSession[j].param.gtp_teid;
decodePDUSessionResourceModify(&sess->param, UE->pduSession[i].param.pdusessionTransfer);
sess->param.UPF_addr_N3 = sessMod->upf_addr;
sess->param.UPF_teid_N3 = sessMod->gtp_teid;
}
}
UE->nb_of_modify_pdusessions = req->nb_pdusessions_tomodify - nb_of_failed_pdusessions;
UE->nb_of_failed_pdusessions = nb_of_failed_pdusessions;
if (UE->nb_of_failed_pdusessions < UE->nb_of_modify_pdusessions) {
if (!all_failed) {
LOG_D(NR_RRC, "generate RRCReconfiguration \n");
rrc_gNB_modify_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
} else { // all pdu modification failed
LOG_I(NR_RRC, "pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n");
MessageDef *msg_fail_p = NULL;
msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP);
} else {
LOG_I(NR_RRC,
"pdu session modify failed, fill NGAP_PDUSESSION_MODIFY_RESP with the pdu session information that failed to modify \n");
MessageDef *msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP);
if (msg_fail_p == NULL) {
LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_fail_p is NULL \n");
return (-1);
......@@ -981,21 +980,16 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
msg->gNB_ue_ngap_id = req->gNB_ue_ngap_id;
msg->nb_of_pdusessions = 0;
for (int i = 0; i < UE->nb_of_failed_pdusessions; i++) {
msg->pdusessions_failed[i].pdusession_id = UE->modify_pdusession[i].param.pdusession_id;
msg->pdusessions_failed[i].cause = UE->modify_pdusession[i].cause;
msg->pdusessions_failed[i].cause_value = UE->modify_pdusession[i].cause_value;
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) {
msg->pdusessions_failed[i].pdusession_id = UE->pduSession[i].param.pdusession_id;
msg->pdusessions_failed[i].cause = UE->pduSession[i].cause;
msg->pdusessions_failed[i].cause_value = UE->pduSession[i].cause_value;
}
}
msg->nb_of_pdusessions_failed = UE->nb_of_failed_pdusessions;
itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p);
UE->nb_of_modify_pdusessions = 0;
UE->nb_of_failed_pdusessions = 0;
memset(UE->modify_pdusession, 0, sizeof(UE->modify_pdusession));
return (0);
}
return 0;
return (0);
}
//------------------------------------------------------------------------------
......@@ -1022,63 +1016,63 @@ rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(
resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
for (int i = 0; i < UE->nb_of_modify_pdusessions; i++) {
if (xid != UE->modify_pdusession[i].xid) {
LOG_W(NR_RRC, "xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", i, UE->modify_pdusession[i].status, xid, UE->modify_pdusession[i].xid);
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
if (xid != UE->pduSession[i].xid) {
LOG_W(NR_RRC, "xid does not correspond (context pdu session index %d, status %d, xid %d/%d) \n ", i, UE->pduSession[i].status, xid, UE->pduSession[i].xid);
continue;
}
if (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_DONE) {
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, UE->modify_pdusession[i].param.pdusession_id, false);
if (UE->pduSession[i].status == PDU_SESSION_STATUS_DONE) {
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, UE->pduSession[i].param.pdusession_id, false);
if (pduSession) {
LOG_I(NR_RRC, "update pdu session %d \n", pduSession->param.pdusession_id);
// Update UE->pduSession
pduSession->status = PDU_SESSION_STATUS_ESTABLISHED;
pduSession->cause = NGAP_CAUSE_NOTHING;
for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) {
pduSession->param.qos[qos_flow_index] = UE->modify_pdusession[i].param.qos[qos_flow_index];
for (int qos_flow_index = 0; qos_flow_index < UE->pduSession[i].param.nb_qos; qos_flow_index++) {
pduSession->param.qos[qos_flow_index] = UE->pduSession[i].param.qos[qos_flow_index];
}
resp->pdusessions[pdu_sessions_done].pdusession_id = UE->modify_pdusession[i].param.pdusession_id;
for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) {
resp->pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = UE->modify_pdusession[i].param.qos[qos_flow_index].qfi;
resp->pdusessions[pdu_sessions_done].pdusession_id = UE->pduSession[i].param.pdusession_id;
for (int qos_flow_index = 0; qos_flow_index < UE->pduSession[i].param.nb_qos; qos_flow_index++) {
resp->pdusessions[pdu_sessions_done].qos[qos_flow_index].qfi = UE->pduSession[i].param.qos[qos_flow_index].qfi;
}
resp->pdusessions[pdu_sessions_done].pdusession_id = UE->modify_pdusession[i].param.pdusession_id;
resp->pdusessions[pdu_sessions_done].nb_of_qos_flow = UE->modify_pdusession[i].param.nb_qos;
resp->pdusessions[pdu_sessions_done].pdusession_id = UE->pduSession[i].param.pdusession_id;
resp->pdusessions[pdu_sessions_done].nb_of_qos_flow = UE->pduSession[i].param.nb_qos;
LOG_I(NR_RRC,
"Modify Resp (msg index %d, pdu session index %d, status %d, xid %d): nb_of_modify_pdusessions %d, pdusession_id %d \n ",
"Modify Resp (msg index %d, pdu session index %d, status %d, xid %d): nb_of_pduSessions %d, pdusession_id %d \n ",
pdu_sessions_done,
i,
UE->modify_pdusession[i].status,
UE->pduSession[i].status,
xid,
UE->nb_of_modify_pdusessions,
UE->nb_of_pdusessions,
resp->pdusessions[pdu_sessions_done].pdusession_id);
pdu_sessions_done++;
} else {
LOG_W(NR_RRC, "PDU SESSION modify of a not existing pdu session %d \n", UE->modify_pdusession[i].param.pdusession_id);
resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_pdusession[i].param.pdusession_id;
LOG_W(NR_RRC, "PDU SESSION modify of a not existing pdu session %d \n", UE->pduSession[i].param.pdusession_id);
resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->pduSession[i].param.pdusession_id;
resp->pdusessions_failed[pdu_sessions_failed].cause = NGAP_CAUSE_RADIO_NETWORK;
resp->pdusessions_failed[pdu_sessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
pdu_sessions_failed++;
}
} else if ((UE->modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) {
} else if ((UE->pduSession[i].status == PDU_SESSION_STATUS_NEW) || (UE->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED)) {
LOG_D(NR_RRC, "PDU SESSION is NEW or already ESTABLISHED\n");
} else if (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_FAILED) {
resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_pdusession[i].param.pdusession_id;
resp->pdusessions_failed[pdu_sessions_failed].cause = UE->modify_pdusession[i].cause;
resp->pdusessions_failed[pdu_sessions_failed].cause_value = UE->modify_pdusession[i].cause_value;
} else if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) {
resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->pduSession[i].param.pdusession_id;
resp->pdusessions_failed[pdu_sessions_failed].cause = UE->pduSession[i].cause;
resp->pdusessions_failed[pdu_sessions_failed].cause_value = UE->pduSession[i].cause_value;
pdu_sessions_failed++;
}
else
LOG_W(NR_RRC,
"Modify pdu session %d, unknown state %d \n ",
UE->modify_pdusession[i].param.pdusession_id,
UE->modify_pdusession[i].status);
UE->pduSession[i].param.pdusession_id,
UE->pduSession[i].status);
}
resp->nb_of_pdusessions = pdu_sessions_done;
resp->nb_of_pdusessions_failed = pdu_sessions_failed;
if (pdu_sessions_done > 0 || pdu_sessions_failed > 0) {
LOG_D(NR_RRC, "NGAP_PDUSESSION_MODIFY_RESP: sending the message: nb_of_pdusessions %d, total pdu session %d\n", UE->nb_of_modify_pdusessions, UE->nb_of_pdusessions);
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);
} else {
itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
......@@ -1179,22 +1173,19 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
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,
NR_UL_DCCH_Message_t *const ul_dcch_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)
//------------------------------------------------------------------------------
{
NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList;
/* 4096 is arbitrary, should be big enough */
void *buf;
NR_UERadioAccessCapabilityInformation_t rac = {0};
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
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);
if (ueCapabilityRATContainerList->list.count == 0) {
LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, UE->rnti);
}
int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf);
......@@ -1242,31 +1233,21 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
memset(resp, 0, sizeof(*resp));
resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
for (int i = 0; i < NB_RB_MAX; i++) {
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
if (xid == UE->pduSession[i].xid) {
resp->pdusession_release[pdu_sessions_released].pdusession_id = UE->pduSession[i].param.pdusession_id;
pdu_sessions_released++;
//clear
memset(&UE->pduSession[i], 0, sizeof(*UE->pduSession));
UE->pduSession[i].status = PDU_SESSION_STATUS_RELEASED;
LOG_W(NR_RRC, "Released pdu session, but code to finish to free memory\n");
}
}
resp->nb_of_pdusessions_released = pdu_sessions_released;
resp->nb_of_pdusessions_failed = UE->nb_release_of_pdusessions;
memcpy(resp->pdusessions_failed, UE->pdusessions_release_failed, sizeof(pdusession_failed_t) * UE->nb_release_of_pdusessions);
LOG_E(NR_RRC, "we have to pack the array!!!\n");
UE->nb_of_pdusessions -= pdu_sessions_released;
resp->nb_of_pdusessions_failed = 0;
LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_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);
//clear xid
for(int i = 0; i < NB_RB_MAX; i++) {
UE->pduSession[i].xid = -1;
}
//clear release pdusessions
UE->nb_release_of_pdusessions = 0;
memset(UE->pdusessions_release_failed, 0, sizeof(UE->pdusessions_release_failed));
}
//------------------------------------------------------------------------------
......@@ -1275,8 +1256,6 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
{
uint32_t gNB_ue_ngap_id;
protocol_ctxt_t ctxt;
uint8_t xid;
uint8_t pdusession_release_drb = 0;
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) {
......@@ -1293,18 +1272,21 @@ 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->rnti, 0, 0);
xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id);
LOG_I(
NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_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);
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);
if (!pduSession) {
LOG_I(NR_RRC, "no pdusession_id \n");
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id;
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause_value = 30;
UE->nb_release_of_pdusessions++;
LOG_I(NR_RRC, "no pdusession_id, AMF requested to close it id=%d\n", cmd->pdusession_release_params[pdusession].pdusession_id);
int j=UE->nb_of_pdusessions++;
UE->pduSession[j].status = PDU_SESSION_STATUS_FAILED;
UE->pduSession[j].param.pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id;
UE->pduSession[j].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->pduSession[j].cause_value = 30;
pduSession->xid = xid;
continue;
}
if (pduSession->status == PDU_SESSION_STATUS_FAILED) {
......@@ -1312,37 +1294,22 @@ int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_
continue;
}
if (pduSession->status == PDU_SESSION_STATUS_ESTABLISHED) {
found = true;
LOG_I(NR_RRC, "RELEASE pdusession %d \n", pduSession->param.pdusession_id);
pduSession->status = PDU_SESSION_STATUS_TORELEASE;
pduSession->xid = xid;
pdusession_release_drb++;
continue;
}
// pdusession_id status NG
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = cmd->pdusession_release_params[pdusession].pdusession_id;
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].cause_value = 0;
UE->nb_release_of_pdusessions++;
}
if (pdusession_release_drb > 0) {
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);
} else {
// gtp tunnel delete
LOG_I(NR_RRC, "gtp tunnel delete \n");
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;
for (int i = 0; i < NB_RB_MAX; i++) {
if (xid == UE->pduSession[i].xid) {
req.pdusession_id[req.num_pdusession++] = UE->gnb_gtp_psi[i];
UE->gnb_gtp_teid[i] = 0;
memset(&UE->gnb_gtp_addrs[i], 0, sizeof(UE->gnb_gtp_addrs[i]));
UE->gnb_gtp_psi[i] = 0;
}
}
gtpv1u_delete_ngu_tunnel(instance, &req);
// NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
......
......@@ -96,12 +96,9 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, uint32_t gNB_ue_ngap_id);
void
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
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_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);
int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance);
......
......@@ -68,11 +68,8 @@ rrc_gNB_ue_context_t *rrc_gNB_allocate_new_ue_context(gNB_RRC_INST *rrc_instance
}
new_p->ue_context.gNB_ue_ngap_id = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator);
for(int i = 0; i < NB_RB_MAX; i++) {
new_p->ue_context.e_rab[i].xid = -1;
for(int i = 0; i < NB_RB_MAX; i++)
new_p->ue_context.pduSession[i].xid = -1;
new_p->ue_context.modify_e_rab[i].xid = -1;
}
LOG_I(NR_RRC, "Returning new RRC UE context RRC ue id: %d\n", new_p->ue_context.gNB_ue_ngap_id);
return(new_p);
......
......@@ -411,11 +411,11 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
tmp.from_gnb=1;
LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d will be deleted for rnti %d\n", ue_context->ue_context.nb_of_e_rabs, rnti);
for (e_rab = 0; e_rab < ue_context->ue_context.nb_of_e_rabs; e_rab++) {
tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.gnb_gtp_ebi[e_rab];
tmp.eps_bearer_id[tmp.num_erab++]= ue_context->ue_context.nsa_gtp_ebi[e_rab];
// erase data
ue_context->ue_context.gnb_gtp_teid[e_rab] = 0;
memset(&ue_context->ue_context.gnb_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.gnb_gtp_addrs[e_rab]));
ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0;
ue_context->ue_context.nsa_gtp_teid[e_rab] = 0;
memset(&ue_context->ue_context.nsa_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.nsa_gtp_addrs[e_rab]));
ue_context->ue_context.nsa_gtp_ebi[e_rab] = 0;
}
gtpv1u_delete_s1u_tunnel(rrc->module_id, &tmp);
/* remove context */
......
......@@ -58,7 +58,7 @@ static void allocCopy(OCTET_STRING_t *out, ngap_pdu_t in)
out->size = in.length;
}
static void allocAddrCopy(BIT_STRING_t *out, ngap_transport_layer_addr_t in)
static void allocAddrCopy(BIT_STRING_t *out, transport_layer_addr_t in)
{
if (in.length) {
out->buf = malloc(in.length);
......
......@@ -762,6 +762,7 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance,
create_tunnel_resp->gnb_NGu_teid[i]=teid;
memcpy(create_tunnel_resp->gnb_addr.buffer,addr,sizeof(addr));
create_tunnel_resp->gnb_addr.length= sizeof(addr);
create_tunnel_resp->pdusession_id[i] = create_tunnel_req->pdusession_id[i];
}
return !GTPNOK;
......
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