Commit c4538995 authored by laurent's avatar laurent

continue code and take review comments

parent a5975312
......@@ -35,7 +35,7 @@ add_library(telnetsrv MODULE
telnetsrv_measurements.c
)
target_link_libraries(telnetsrv PRIVATE history)
target_link_libraries(telnetsrv PRIVATE asn1_nr_rrc asn1_lte_rrc)
target_link_libraries(telnetsrv PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_ngap)
message(STATUS "Add enb specific telnet functions in libtelnetsrv_enb.so")
add_library(telnetsrv_enb MODULE
......@@ -43,7 +43,7 @@ add_library(telnetsrv_enb MODULE
telnetsrv_enb_phycmd.c
)
add_dependencies(telnetsrv telnetsrv_enb)
target_link_libraries(telnetsrv_enb PRIVATE asn1_nr_rrc asn1_lte_rrc)
target_link_libraries(telnetsrv_enb PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_ngap )
message(STATUS "No specific telnet functions for gnb")
......@@ -52,7 +52,7 @@ message(STATUS "No specific telnet functions for 4Gue")
message(STATUS "Add 5Gue specific telnet functions in libtelnetsrv_5Gue.so")
add_library(telnetsrv_5Gue MODULE telnetsrv_5Gue_measurements.c)
add_dependencies(telnetsrv telnetsrv_5Gue)
target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc asn1_lte_rrc)
target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc asn1_lte_rrc asn1_ngap)
# all libraries should be written to root build dir
set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue
......
......@@ -300,7 +300,7 @@ typedef enum pdusession_qosflow_mapping_ind_e{
typedef struct pdusession_associate_qosflow_s{
uint8_t qfi;
pdusession_qosflow_mapping_ind_t qos_flow_mapping_ind;
}pdusession_associate_qosflow_t;
} pdusession_associate_qosflow_t;
typedef struct pdusession_setup_s {
/* Unique pdusession_id for the UE. */
......@@ -319,22 +319,6 @@ typedef struct pdusession_setup_s {
pdusession_associate_qosflow_t associated_qos_flows[QOSFLOW_MAX_VALUE];
} pdusession_setup_t;
typedef struct pdusession_admitted_tobe_added_s {
/* Unique pdusession_id for the UE. */
uint8_t pdusession_id;
/* Unique drb_ID for the UE. */
uint8_t drb_ID;
/* The transport layer address for the IP packets */
ngap_transport_layer_addr_t gnb_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
} pdusession_admitted_tobe_added_t;
typedef struct pdusession_tobeswitched_s {
/* Unique pdusession_id for the UE. */
uint8_t pdusession_id;
......@@ -610,7 +594,7 @@ typedef struct ngap_initial_context_setup_req_s {
/* UE id for initial connection to NGAP */
uint32_t gNB_ue_ngap_id;
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* UE aggregate maximum bitrate */
ngap_ambr_t ue_ambr;
......@@ -665,14 +649,22 @@ typedef struct ngap_paging_ind_s {
ngap_paging_priority_t paging_priority;
} ngap_paging_ind_t;
typedef struct {
/* Unique pdusession_id for the UE. */
int pdusession_id;
ngap_pdu_t nas_pdu;
ngap_pdu_t pdusessionTransfer;
} pdusession_setup_req_t;
typedef struct ngap_pdusession_setup_req_s {
/* UE id for initial connection to NGAP */
uint32_t gNB_ue_ngap_id;
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* S-NSSAI */
// Fixme: illogical, nssai is part of each pdu session
ngap_allowed_NSSAI_t allowed_nssai[8];
/* Number of pdusession to be setup in the list */
......@@ -712,7 +704,7 @@ typedef struct ngap_path_switch_req_s {
pdusession_setup_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION];
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
ngap_guami_t ue_guami;
......@@ -730,7 +722,7 @@ typedef struct ngap_path_switch_req_ack_s {
uint32_t gNB_ue_ngap_id;
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* UE aggregate maximum bitrate */
ngap_ambr_t ue_ambr;
......@@ -758,7 +750,7 @@ typedef struct ngap_pdusession_modification_ind_s {
uint32_t gNB_ue_ngap_id;
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* Number of pdusession setup-ed in the list */
uint8_t nb_of_pdusessions_tobemodified;
......@@ -802,7 +794,7 @@ typedef struct ngap_ue_release_req_s {
typedef struct ngap_pdusession_modify_req_s {
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* gNB ue ngap id as initialized by NGAP layer */
uint32_t gNB_ue_ngap_id;
......@@ -830,7 +822,7 @@ typedef struct ngap_pdusession_modify_resp_s {
typedef struct ngap_pdusession_release_command_s {
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* gNB ue ngap id as initialized by NGAP layer */
uint32_t gNB_ue_ngap_id;
......@@ -848,7 +840,7 @@ typedef struct ngap_pdusession_release_command_s {
typedef struct ngap_pdusession_release_resp_s {
/* AMF UE id */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* gNB ue ngap id as initialized by NGAP layer */
uint32_t gNB_ue_ngap_id;
......
......@@ -230,8 +230,7 @@ typedef struct protocol_ctxt_s {
#define ENB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE
//NR
#define GNB_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD
#define GNB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE
#define GNB_MODULE_ID_TO_INSTANCE(mODULE_iD) mODULE_iD
#define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \
do { \
......
......@@ -57,7 +57,7 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_as
f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams;
f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams;
f1ap_cu_data->default_sctp_stream_id = 0;
if (RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)]->node_type != ngran_gNB_CUCP) {
if (RC.nrrrc[instance]->node_type != ngran_gNB_CUCP) {
getCxt(CUtype, instance)->gtpInst = cu_task_create_gtpu_instance(IPaddrs);
AssertFatal(getCxt(CUtype, instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener");
} else
......
......@@ -958,7 +958,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance,
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance);
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti);
if (ue_context_p) {
MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE);
......
......@@ -2904,8 +2904,7 @@ void send_initial_ul_rrc_message(module_id_t module_id,
/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */
if (NODE_IS_DU(RC.nrrrc[module_id]->node_type)) {
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_id]);
ue_context_p->ue_id_rnti = rnti;
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_id]);
ue_context_p->ue_context.rnti = rnti;
ue_context_p->ue_context.random_ue_identity = rnti;
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_id]->rrc_ue_head, ue_context_p);
......
......@@ -118,7 +118,7 @@ int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t *
/* TODO: drop the RRC context */
gNB_RRC_INST *rrc = RC.nrrrc[module_id];
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, dl_rrc->rnti);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, dl_rrc->rnti);
gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
ue_p->SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList;
ue_p->masterCellGroup = cellGroup;
......
......@@ -162,8 +162,7 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP,
const rnti_t rntiP,
const int dl_bwp_id,
const int ul_bwp_id) {
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[module_idP], rntiP);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[module_idP], rntiP);
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP, 0);
......@@ -177,10 +176,7 @@ void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP,
const frame_t frameP,
const sub_frame_t subframeP,
const rnti_t rntiP) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
ue_context_p = rrc_gNB_get_ue_context(
RC.nrrrc[Mod_instP],
rntiP);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_instP], rntiP);
if (ue_context_p != NULL) {
LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
......@@ -195,8 +191,7 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP,
const frame_t frameP,
const sub_frame_t subframeP,
const rnti_t rntiP) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_instP], rntiP);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_instP], rntiP);
if (ue_context_p != NULL) {
LOG_W(RRC,"Frame %d, Subframe %d: UE %x UL failure reset, deactivating timer\n",frameP,subframeP,rntiP);
ue_context_p->ue_context.ul_failure_timer=0;
......
......@@ -1521,10 +1521,7 @@ int16_t do_RRCReconfiguration(
}
if(cellGroupConfig!=NULL){
update_cellGroupConfig(cellGroupConfig,
ue_context_pP->local_uid,
ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL,
configuration);
update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
NULL,
......
......@@ -187,7 +187,7 @@ 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) {
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(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);
......
......@@ -36,7 +36,7 @@
extern RAN_CONTEXT_t RC;
static void cucp_cuup_bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *const req, instance_t instance) {
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(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);
......
......@@ -269,9 +269,6 @@ typedef struct pdu_session_param_s {
uint8_t xid; // transaction_id
NGAP_Cause_PR cause;
uint8_t cause_value;
ngap_pdu_t nas_pdu;
ngap_pdu_t pdusessionTransfer;
} rrc_pdu_session_param_t;
typedef struct gNB_RRC_UE_s {
......@@ -334,7 +331,7 @@ typedef struct gNB_RRC_UE_s {
/* Information from S1AP initial_context_setup_req */
uint32_t gNB_ue_s1ap_id :24;
uint32_t gNB_ue_ngap_id;
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
nr_rrc_guami_t ue_guami;
ngap_security_capabilities_t security_capabilities;
......@@ -404,15 +401,6 @@ typedef struct gNB_RRC_UE_s {
typedef struct rrc_gNB_ue_context_s {
/* Tree related data */
RB_ENTRY(rrc_gNB_ue_context_s) entries;
/* Uniquely identifies the UE between MME and eNB within the eNB.
* This id is encoded on 24bits.
*/
ue_id_t ue_id_rnti;
// another key for protocol layers but should not be used as a key for RB tree
uid_t local_uid;
/* UE id for initial connection to NGAP */
struct gNB_RRC_UE_s ue_context;
} rrc_gNB_ue_context_t;
......
......@@ -64,11 +64,11 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge(
rrc_gNB_ue_context_t *const ue_context_pP
);
struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_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);
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m);
void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti);
......@@ -217,9 +217,5 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
uint8_t *const kUPint,
struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
int rrc_gNB_generate_pcch_msg(uint32_t tmsi,
uint8_t paging_drx,
instance_t instance,
uint8_t CC_id);
int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id);
#endif
......@@ -196,7 +196,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
pthread_mutex_unlock(&rrc->cell_info_mutex);
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = configuration->scd;
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
......@@ -531,30 +531,24 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
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;
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
/* Add all NAS PDUs to the list */
for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
OCTET_STRING_fromBuf(dedicatedNAS_Message,
(char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer,
ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length);
asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
OCTET_STRING_fromBuf(msg, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length);
}
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE");
}
if (ue_context_pP->ue_context.nas_pdu.length) {
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
OCTET_STRING_fromBuf(dedicatedNAS_Message,
(char *)ue_context_pP->ue_context.nas_pdu.buffer,
ue_context_pP->ue_context.nas_pdu.length);
asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
if (ue_p->nas_pdu.length) {
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
OCTET_STRING_fromBuf(msg, (char *)ue_p->nas_pdu.buffer, ue_p->nas_pdu.length);
}
/* If list is empty free the list and reset the address */
......@@ -566,7 +560,6 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
NR_MeasConfig_t *measconfig = get_defaultMeasConfig(&rrc->configuration);
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ctxt_pP,
buffer,
......@@ -676,53 +669,53 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
DRB_configList = &ue_context_pP->ue_context.DRB_configList;
DRB_configList = &ue_p->DRB_configList;
if (*DRB_configList) {
free(*DRB_configList);
}
*DRB_configList = CALLOC(1, sizeof(**DRB_configList));
memset(*DRB_configList, 0, sizeof(**DRB_configList));
DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid];
DRB_configList2 = &ue_p->DRB_configList2[xid];
if (*DRB_configList2) {
free(*DRB_configList2);
}
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
memset(*DRB_configList2, 0, sizeof(**DRB_configList2));
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
if (pdu_sessions_done >= ue_context_pP->ue_context.nb_of_pdusessions) {
for (i = 0; i < ue_p->nb_of_pdusessions; i++) {
if (pdu_sessions_done >= ue_p->nb_of_pdusessions) {
break;
}
if (ue_context_pP->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
if (ue_p->pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
continue;
}
ue_context_pP->ue_context.pduSession[i].xid = xid;
ue_p->pduSession[i].xid = xid;
for(long drb_id_add = 1; drb_id_add <= nb_drb_to_setup; drb_id_add++){
uint8_t drb_id;
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) {
switch (ue_context_pP->ue_context.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 ... 4: /* GBR */
drb_id = next_available_drb(ue_p, &ue_context_pP->ue_context.pduSession[i], GBR_FLOW);
drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], GBR_FLOW);
break;
case 5 ... 9: /* Non-GBR */
if(rrc->configuration.drbs > 1) /* Force the creation from gNB Conf file - Should be used only in noS1 mode and rfsim for testing purposes. */
drb_id = next_available_drb(ue_p, &ue_context_pP->ue_context.pduSession[i], GBR_FLOW);
drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], GBR_FLOW);
else
drb_id = next_available_drb(ue_p, &ue_context_pP->ue_context.pduSession[i], NONGBR_FLOW);
drb_id = next_available_drb(ue_p, &ue_p->pduSession[i], NONGBR_FLOW);
break;
default:
LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI);
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_FAILED;
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;
pdu_sessions_done++;
continue;
}
switch(ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level) {
switch (ue_p->pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level) {
case NGAP_PRIORITY_LEVEL_HIGHEST:
drb_priority[drb_id-1] = 1;
break;
......@@ -777,12 +770,7 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
if(drb_is_active(ue_p, drb_id)){ /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/
nb_drb_to_setup--;
} else {
NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p,
drb_id,
&ue_context_pP->ue_context.pduSession[i],
rrc->configuration.enable_sdap,
rrc->security.do_drb_integrity,
rrc->security.do_drb_ciphering);
NR_DRB_ToAddMod_t *DRB_config = generateDRB(ue_p, drb_id, &ue_p->pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering);
if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity;
asn1cSeqAdd(&(*DRB_configList)->list, DRB_config);
asn1cSeqAdd(&(*DRB_configList2)->list, DRB_config);
......@@ -791,8 +779,8 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP,
}
}
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
ue_context_pP->ue_context.pduSession[i].xid = xid;
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
ue_p->pduSession[i].xid = xid;
}
}
......@@ -811,7 +799,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
int xid = -1;
int drb_id_to_setup_start = 1;
NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList;
int nb_drb_to_setup = DRB_configList->list.count;
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL;
......@@ -822,21 +811,21 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
NR_DRB_ToAddMod_t *DRB_config = DRB_configList->list.array[i];
if (drb_id_to_setup_start == 1)
drb_id_to_setup_start = DRB_config->drb_Identity;
int j = ue_context_pP->ue_context.nb_of_pdusessions - 1;
int j = ue_p->nb_of_pdusessions - 1;
AssertFatal(j >= 0, "");
if (ue_context_pP->ue_context.pduSession[j].param.nas_pdu.buffer != NULL) {
if (ue_p->pduSession[j].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_context_pP->ue_context.pduSession[j].param.nas_pdu.buffer, ue_context_pP->ue_context.pduSession[j].param.nas_pdu.length);
OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)ue_p->pduSession[j].param.nas_pdu.buffer, ue_p->pduSession[j].param.nas_pdu.length);
asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_context_pP->ue_context.pduSession[j].param.nas_pdu.length, j);
LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[j].param.nas_pdu.length, j);
} else {
// TODO
LOG_E(NR_RRC, "no NAS info (pdusession idx %d)\n", j);
}
xid = ue_context_pP->ue_context.pduSession[j].xid;
xid = ue_p->pduSession[j].xid;
}
/* If list is empty free the list and reset the address */
......@@ -849,7 +838,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
// FIXME: fill_mastercellGroupConfig() won't fill the right priorities or
// bearer IDs for the DRBs
fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
}
else{
LOG_I(NR_RRC, "Master cell group originating from the DU \n");
......@@ -858,7 +847,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid);
NR_SRB_ToAddModList_t *SRB_configList2 = NULL;
SRB_configList2 = ue_context_pP->ue_context.SRB_configList2[xid];
SRB_configList2 = ue_p->SRB_configList2[xid];
uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReconfiguration(ctxt_pP,
......@@ -880,20 +869,24 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Reconfiguration\n");
/* Free all NAS PDUs */
for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
if (ue_context_pP->ue_context.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_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
ue_context_pP->ue_context.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;
}
}
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_context_pP->ue_context.rnti);
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_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
nr_rrc_data_req(
ctxt_pP,
......@@ -914,19 +907,15 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
NULL,
NULL,
0,
ue_context_pP->ue_context.rnti,
ue_context_pP->ue_context.masterCellGroup);
ue_p->rnti,
ue_p->masterCellGroup);
uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ?
NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS;
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
: NR_RRC_RECONFIGURATION_DELAY_MS;
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
ue_context_pP->ue_context.rnti,
*rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
delay_ms);
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *rrc->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
}
}
......@@ -947,48 +936,48 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
int i, j;
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
DRB_configList = &ue_context_pP->ue_context.DRB_configList;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
DRB_configList = &ue_p->DRB_configList;
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_context_pP->ue_context.nb_of_modify_pdusessions; i++) {
for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) {
// bypass the new and already configured pdu sessions
if (ue_context_pP->ue_context.modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) {
ue_context_pP->ue_context.modify_pdusession[i].xid = xid;
if (ue_p->modify_pdusession[i].status >= PDU_SESSION_STATUS_DONE) {
ue_p->modify_pdusession[i].xid = xid;
continue;
}
if (ue_context_pP->ue_context.modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) {
if (ue_p->modify_pdusession[i].cause != NGAP_CAUSE_NOTHING) {
// set xid of failure pdu session
ue_context_pP->ue_context.modify_pdusession[i].xid = xid;
ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED;
ue_p->modify_pdusession[i].xid = xid;
ue_p->modify_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_context_pP->ue_context.modify_pdusession[i].param.pdusession_id) {
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];
break;
}
}
if (DRB_config == NULL) {
ue_context_pP->ue_context.modify_pdusession[i].xid = xid;
ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED;
ue_context_pP->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_context_pP->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unspecified;
ue_context_pP->ue_context.nb_of_failed_pdusessions++;
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++;
continue;
}
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.modify_pdusession[i].param.nb_qos; qos_flow_index++) {
switch (ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].fiveQI) {
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) {
case 1: //100ms
case 2: //150ms
case 3: //50ms
......@@ -1002,41 +991,39 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
break;
default:
LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].fiveQI);
ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_FAILED;
ue_context_pP->ue_context.modify_pdusession[i].xid = xid;
ue_context_pP->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
ue_context_pP->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_not_supported_5QI_value;
ue_context_pP->ue_context.nb_of_failed_pdusessions++;
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++;
continue;
}
LOG_I(NR_RRC, "PDU SESSION ID %ld, DRB ID %ld (index %d), QOS flow %d, 5QI %ld \n",
DRB_config->cnAssociation->choice.sdap_Config->pdu_Session,
DRB_config->drb_Identity, i,
qos_flow_index,
ue_context_pP->ue_context.modify_pdusession[i].param.qos[qos_flow_index].fiveQI
);
LOG_I(NR_RRC,
"PDU SESSION ID %ld, DRB ID %ld (index %d), QOS flow %d, 5QI %ld \n",
DRB_config->cnAssociation->choice.sdap_Config->pdu_Session,
DRB_config->drb_Identity,
i,
qos_flow_index,
ue_p->modify_pdusession[i].param.qos[qos_flow_index].fiveQI);
}
asn1cSeqAdd(&DRB_configList2->list, DRB_config);
ue_context_pP->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_DONE;
ue_context_pP->ue_context.modify_pdusession[i].xid = xid;
ue_p->modify_pdusession[i].status = PDU_SESSION_STATUS_DONE;
ue_p->modify_pdusession[i].xid = xid;
if (ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer != NULL) {
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_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer,
ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.length);
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);
LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length,
ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id);
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);
} else {
// TODO
LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", ue_context_pP->ue_context.modify_pdusession[i].param.pdusession_id);
LOG_E(NR_RRC, "no NAS info (pdusession id %d)\n", ue_p->modify_pdusession[i].param.pdusession_id);
}
}
......@@ -1066,20 +1053,24 @@ 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_context_pP->ue_context.nb_of_modify_pdusessions; i++) {
if (ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer != NULL) {
for (i = 0; i < ue_p->nb_of_modify_pdusessions; i++) {
if (ue_p->modify_pdusession[i].param.nas_pdu.buffer != NULL) {
/* Free the NAS PDU buffer and invalidate it */
free(ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer);
ue_context_pP->ue_context.modify_pdusession[i].param.nas_pdu.buffer = NULL;
free(ue_p->modify_pdusession[i].param.nas_pdu.buffer);
ue_p->modify_pdusession[i].param.nas_pdu.buffer = NULL;
}
}
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_context_pP->ue_context.rnti);
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_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
nr_rrc_data_req(
ctxt_pP,
......@@ -1091,16 +1082,12 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
PDCP_TRANSMISSION_MODE_CONTROL);
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ?
NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS;
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
: NR_RRC_RECONFIGURATION_DELAY_MS;
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
ue_context_pP->ue_context.rnti,
*RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
delay_ms);
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
}
}
......@@ -1120,15 +1107,16 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*dedicatedNAS_MessageList = NULL;
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
DRB_Release_configList2 = &ue_context_pP->ue_context.DRB_Release_configList2[xid];
DRB_Release_configList2 = &ue_p->DRB_Release_configList2[xid];
if (*DRB_Release_configList2) {
free(*DRB_Release_configList2);
}
*DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
for(i = 0; i < NB_RB_MAX; i++) {
if((ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pduSession[i].xid == xid) {
if ((ue_p->pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_p->pduSession[i].xid == xid) {
DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t));
*DRB_release = i+1;
asn1cSeqAdd(&(*DRB_Release_configList2)->list, DRB_release);
......@@ -1152,11 +1140,11 @@ 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_context_pP->ue_context.pdu_session_release_command_flag = 1;
ue_p->pdu_session_release_command_flag = 1;
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
ue_context_pP->ue_context.pdu_session_release_command_flag = 1;
ue_p->pdu_session_release_command_flag = 1;
/* Free all NAS PDUs */
if (nas_length > 0) {
......@@ -1164,12 +1152,16 @@ 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_context_pP->ue_context.rnti);
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_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH);
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
nr_rrc_data_req(
ctxt_pP,
DCCH,
......@@ -1180,16 +1172,12 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release(
PDCP_TRANSMISSION_MODE_CONTROL);
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ?
NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS;
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
: NR_RRC_RECONFIGURATION_DELAY_MS;
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
ue_context_pP->ue_context.rnti,
*RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
delay_ms);
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
}
}
......@@ -1209,33 +1197,26 @@ rrc_gNB_process_RRCReconfigurationComplete(
uint8_t *kRRCint = NULL;
uint8_t *kUPenc = NULL;
uint8_t *kUPint = NULL;
NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid];
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid];
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList2[xid];
NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList2[xid];
NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_p->DRB_Release_configList2[xid];
NR_DRB_Identity_t *drb_id_p = NULL;
// uint8_t nr_DRB2LCHAN[8];
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
ue_p->ue_reestablishment_timer = 0;
/* Derive the keys from kgnb */
if (DRB_configList != NULL) {
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kUPenc);
nr_derive_key_up_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb,
&kUPint);
nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc);
nr_derive_key_up_int(ue_p->integrity_algorithm, ue_p->kgnb, &kUPint);
}
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCenc);
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm,
ue_context_pP->ue_context.kgnb,
&kRRCint);
nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc);
nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint);
/* Refresh SRBs/DRBs */
LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_context_pP->ue_context.rnti);
LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti);
ue_id_t reestablish_ue_id = 0;
if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) {
......@@ -1252,48 +1233,44 @@ rrc_gNB_process_RRCReconfigurationComplete(
}
}
nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRB_configList, (ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm, kRRCenc, kRRCint);
nr_pdcp_add_srbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, SRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kRRCenc, kRRCint);
nr_pdcp_add_drbs(ctxt_pP->enb_flag,
ctxt_pP->rntiMaybeUEid,
reestablish_ue_id,
DRB_configList,
(ue_context_pP->ue_context.integrity_algorithm << 4) | ue_context_pP->ue_context.ciphering_algorithm,
(ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm,
kUPenc,
kUPint,
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL);
/* Refresh SRBs/DRBs */
if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %04x\n",ue_context_pP->ue_context.rnti);
LOG_D(NR_RRC, "Configuring RLC DRBs/SRBs for UE %04x\n", ue_p->rnti);
nr_rrc_rlc_config_asn1_req(ctxt_pP,
SRB_configList, // NULL,
DRB_configList,
DRB_Release_configList2,
get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL);
get_softmodem_params()->sa ? ue_p->masterCellGroup->rlc_BearerToAddModList : NULL);
}
/* Set the SRB active in UE context */
if (SRB_configList != NULL) {
for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) {
if (SRB_configList->list.array[i]->srb_Identity == 1) {
ue_context_pP->ue_context.Srb[1].Active = 1;
ue_context_pP->ue_context.Srb[1].Srb_info.Srb_id = 1;
ue_p->Srb[1].Active = 1;
ue_p->Srb[1].Srb_info.Srb_id = 1;
} else if (SRB_configList->list.array[i]->srb_Identity == 2) {
ue_context_pP->ue_context.Srb[2].Active = 1;
ue_context_pP->ue_context.Srb[2].Srb_info.Srb_id = 2;
LOG_I(NR_RRC, "[gNB %d] Frame %d CC %d : SRB2 is now active\n", ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.primaryCC_id);
ue_p->Srb[2].Active = 1;
ue_p->Srb[2].Srb_info.Srb_id = 2;
LOG_I(NR_RRC, "[gNB %d] Frame %d CC %d : SRB2 is now active\n", ctxt_pP->module_id, ctxt_pP->frame, ue_p->primaryCC_id);
} else {
LOG_W(NR_RRC,"[gNB %d] Frame %d CC %d: invalid SRB identity %ld\n",
ctxt_pP->module_id,
ctxt_pP->frame,
ue_context_pP->ue_context.primaryCC_id,
SRB_configList->list.array[i]->srb_Identity);
LOG_W(NR_RRC, "[gNB %d] Frame %d CC %d: invalid SRB identity %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ue_p->primaryCC_id, SRB_configList->list.array[i]->srb_Identity);
}
}
free(SRB_configList);
ue_context_pP->ue_context.SRB_configList2[xid] = NULL;
ue_p->SRB_configList2[xid] = NULL;
}
/* Loop through DRBs and establish if necessary */
......@@ -1309,8 +1286,8 @@ rrc_gNB_process_RRCReconfigurationComplete(
(int)DRB_configList->list.array[i]->drb_Identity);
//(int)*DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel);
if (ue_context_pP->ue_context.DRB_active[drb_id - 1] == 0) {
ue_context_pP->ue_context.DRB_active[drb_id - 1] = DRB_ACTIVE;
if (ue_p->DRB_active[drb_id - 1] == 0) {
ue_p->DRB_active[drb_id - 1] = DRB_ACTIVE;
LOG_D(NR_RRC, "[gNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n",
ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity);
......@@ -1324,7 +1301,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
// rrc_mac_config_req_eNB
} else { // remove LCHAN from MAC/PHY
if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
if (ue_p->DRB_active[drb_id] == 1) {
/* TODO : It may be needed if gNB goes into full stack working. */
// DRB has just been removed so remove RLC + PDCP for DRB
/* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE,
......@@ -1337,18 +1314,18 @@ rrc_gNB_process_RRCReconfigurationComplete(
nr_DRB2LCHAN[i]);*/
}
//ue_context_pP->ue_context.DRB_active[drb_id] = 0;
// ue_p->DRB_active[drb_id] = 0;
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
// rrc_mac_config_req_eNB
} // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0)
} // end else of if (ue_p->DRB_active[drb_id] == 0)
} // end if (DRB_configList->list.array[i])
} // end for (int i = 0; i < DRB_configList->list.count; i++)
free(DRB_configList);
ue_context_pP->ue_context.DRB_configList2[xid] = NULL;
ue_p->DRB_configList2[xid] = NULL;
} // end if DRB_configList != NULL
if(DRB_Release_configList2 != NULL) {
......@@ -1357,14 +1334,14 @@ rrc_gNB_process_RRCReconfigurationComplete(
drb_id_p = DRB_Release_configList2->list.array[i];
drb_id = *drb_id_p;
if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
ue_context_pP->ue_context.DRB_active[drb_id] = 0;
if (ue_p->DRB_active[drb_id] == 1) {
ue_p->DRB_active[drb_id] = 0;
}
}
}
free(DRB_Release_configList2);
ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL;
ue_p->DRB_Release_configList2[xid] = NULL;
}
}
......@@ -1384,13 +1361,14 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
module_id_t module_id = ctxt_pP->module_id;
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
int enable_ciphering = 0;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
// Need to drop spCellConfig when there is a RRCReestablishment
// Save spCellConfig in spCellConfigReestablishment to recover after Reestablishment is completed
ue_context_pP->ue_context.spCellConfigReestablishment = ue_context_pP->ue_context.masterCellGroup->spCellConfig;
ue_context_pP->ue_context.masterCellGroup->spCellConfig = NULL;
ue_p->spCellConfigReestablishment = ue_p->masterCellGroup->spCellConfig;
ue_p->masterCellGroup->spCellConfig = NULL;
SRB_configList = &(ue_context_pP->ue_context.SRB_configList);
SRB_configList = &(ue_p->SRB_configList);
uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_RRCReestablishment(ctxt_pP,
......@@ -1423,11 +1401,11 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
uint8_t *kUPenc = NULL;
/* Derive the keys from kgnb */
if (SRB_configList != NULL) {
nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, &kUPenc);
nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc);
}
nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kgnb, &kRRCenc);
nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kgnb, &kRRCint);
nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc);
nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint);
/* Configure SRB1 for UE */
if (*SRB_configList != NULL) {
......@@ -1444,16 +1422,15 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP,
}
} // if (*SRB_configList != NULL)
LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.integrity_algorithm);
pdcp_config_set_security(
ctxt_pP,
NULL, /* pdcp_pP not used anymore in NR */
DCCH,
DCCH + 2,
enable_ciphering ? ue_context_pP->ue_context.ciphering_algorithm | (ue_context_pP->ue_context.integrity_algorithm << 4) : 0 | (ue_context_pP->ue_context.integrity_algorithm << 4),
kRRCenc,
kRRCint,
kUPenc);
LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm);
pdcp_config_set_security(ctxt_pP,
NULL, /* pdcp_pP not used anymore in NR */
DCCH,
DCCH + 2,
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4),
kRRCenc,
kRRCint,
kUPenc);
if (!NODE_IS_CU(rrc->node_type)) {
apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid);
......@@ -1469,9 +1446,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
LOG_I(NR_RRC,
PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing NR_RRCReestablishmentComplete from UE (SRB1 Active)\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList;
NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList;
NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList;
NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList;
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
NR_DRB_ToAddModList_t **DRB_configList2 = NULL;
NR_SRB_ToAddMod_t *SRB2_config = NULL;
......@@ -1481,10 +1459,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
int ret = 0;
ue_context_pP->ue_context.StatusRrc = NR_RRC_CONNECTED;
ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED
ue_context_pP->ue_context.reestablishment_xid = new_xid;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
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;
SRB_configList2 = &ue_p->SRB_configList2[xid];
// get old configuration of SRB2
if (*SRB_configList2 != NULL) {
......@@ -1495,7 +1473,7 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) {
LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid);
LOG_D(NR_RRC, "get SRB2_config from (ue_p->SRB_configList2[%d])\n", xid);
SRB2_config = (*SRB_configList2)->list.array[i];
SRB2_config->reestablishPDCP = CALLOC(1, sizeof(*SRB2_config->reestablishPDCP));
*SRB2_config->reestablishPDCP = NR_SRB_ToAddMod__reestablishPDCP_true;
......@@ -1507,12 +1485,12 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
// SRB2_config = CALLOC(1, sizeof(*SRB2_config));
// SRB2_config->srb_Identity = 2;
SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[new_xid]);
DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[new_xid]);
SRB_configList2 = &(ue_p->SRB_configList2[new_xid]);
DRB_configList2 = &(ue_p->DRB_configList2[new_xid]);
if (*SRB_configList2) {
free(*SRB_configList2);
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", new_xid);
LOG_D(NR_RRC, "free(ue_p->SRB_configList2[%d])\n", new_xid);
}
*SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
......@@ -1521,9 +1499,8 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
// Add SRB2 to SRB configuration list
asn1cSeqAdd(&SRB_configList->list, SRB2_config);
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n",
SRB2_config->srb_Identity);
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid);
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList\n", SRB2_config->srb_Identity);
LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_p->SRB_configList2[%d]\n", SRB2_config->srb_Identity, new_xid);
} else {
// SRB configuration list only contains SRB1.
LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n");
......@@ -1531,13 +1508,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
if (*DRB_configList2) {
free(*DRB_configList2);
LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", new_xid);
LOG_D(NR_RRC, "free(ue_p->DRB_configList2[%d])\n", new_xid);
}
*DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
if (DRB_configList != NULL) {
LOG_D(NR_RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n");
LOG_D(NR_RRC, "get DRB_config from (ue_p->DRB_configList)\n");
for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
DRB_config = DRB_configList->list.array[i];
......@@ -1547,31 +1524,23 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
}
}
ue_context_pP->ue_context.Srb[1].Active = 1;
// ue_context_pP->ue_context.Srb[2].Srb_info.Srb_id = 2;
ue_p->Srb[1].Active = 1;
// ue_p->Srb[2].Srb_info.Srb_id = 2;
if (get_softmodem_params()->sa) {
hashtable_rc_t h_rc;
int j;
uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
uint32_t gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id;
gNB_RRC_INST *rrc_instance_p = RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];
AssertFatal(false, "rework identity mapping \n");
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
/* Save e RAB information for later */
for ( j = 0, i = 0; i < NB_RB_MAX; i++) {
if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) {
create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id;
int j;
for (j = 0, i = 0; i < NB_RB_MAX; i++) {
if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) {
create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id;
create_tunnel_req.incoming_rb_id[j] = i+1;
create_tunnel_req.outgoing_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid;
create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid;
// to be developped, use the first QFI only
create_tunnel_req.outgoing_qfi[j] = ue_context_pP->ue_context.pduSession[i].param.qos[0].qfi;
memcpy(create_tunnel_req.dst_addr[j].buffer,
ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer,
sizeof(uint8_t)*20);
create_tunnel_req.dst_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length;
create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi;
memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20);
create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length;
j++;
}
}
......@@ -1584,39 +1553,20 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx
reestablish_rnti);
if ( ret != 0 ) {
LOG_E(NR_RRC,"gtpv1u_update_ngu_tunnel failed,start to release UE %x\n",reestablish_rnti);
AssertFatal(false, "\n");
/*
// update s1u tunnel failed,reset rnti?
if (gNB_ue_ngap_id > 0) {
h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p);
if (h_rc == HASH_TABLE_OK ) {
rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti;
}
}
if (ue_initial_id != 0) {
h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p);
if (h_rc == HASH_TABLE_OK ) {
rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti;
}
}
*/
ue_context_pP->ue_context.ue_release_timer_s1 = 1;
ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100;
ue_context_pP->ue_context.ue_release_timer = 0;
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
ue_context_pP->ue_context.ul_failure_timer = 0;
LOG_E(NR_RRC, "gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti);
ue_p->ue_release_timer_s1 = 1;
ue_p->ue_release_timer_thres_s1 = 100;
ue_p->ue_release_timer = 0;
ue_p->ue_reestablishment_timer = 0;
ue_p->ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
ue_p->ul_failure_timer = 0;
return;
}
}
/* Update RNTI in ue_context */
ue_context_pP->ue_context.rnti = ctxt_pP->rntiMaybeUEid;
LOG_I(NR_RRC, "Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid);
ue_p->rnti = ctxt_pP->rntiMaybeUEid;
if (get_softmodem_params()->sa) {
uint8_t send_security_mode_command = false;
......@@ -1628,31 +1578,29 @@ if (h_rc == HASH_TABLE_OK ) {
}
uint8_t drb_id_to_setup_start = DRB_configList ? DRB_configList->list.array[0]->drb_Identity : 1;
uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_context_pP->ue_context.nb_of_pdusessions;
uint8_t nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : ue_p->nb_of_pdusessions;
/* TODO: hardcoded to 13 for the time being, to be changed? */
long drb_priority[NGAP_MAX_DRBS_PER_UE] = {13};
/* Add all NAS PDUs to the list */
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
for (i = 0; i < ue_p->nb_of_pdusessions; i++) {
/* TODO parameters yet to process ... */
/* TODO should test if pdu session are Ok before! */
ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE;
ue_context_pP->ue_context.pduSession[i].xid = xid;
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE");
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
ue_p->pduSession[i].xid = xid;
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE");
}
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
// Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment
ue_context_pP->ue_context.masterCellGroup->spCellConfig = ue_context_pP->ue_context.spCellConfigReestablishment;
ue_context_pP->ue_context.spCellConfigReestablishment = NULL;
cellGroupConfig->spCellConfig = ue_context_pP->ue_context.masterCellGroup->spCellConfig;
cellGroupConfig->physicalCellGroupConfig = ue_context_pP->ue_context.masterCellGroup->physicalCellGroupConfig;
ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment;
ue_p->spCellConfigReestablishment = NULL;
cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig;
cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig;
fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
fill_mastercellGroupConfig(cellGroupConfig, ue_p->masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
for(i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC = CALLOC(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC));
......@@ -1680,11 +1628,11 @@ if (h_rc == HASH_TABLE_OK ) {
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
/* Free all NAS PDUs */
for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) {
if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) {
for (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_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer);
ue_context_pP->ue_context.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;
}
}
......@@ -1692,13 +1640,13 @@ if (h_rc == HASH_TABLE_OK ) {
LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n");
return;
} else {
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\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 %04x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
ctxt_pP->frame,
ctxt_pP->module_id,
size,
ue_context_pP->ue_context.rnti,
ue_p->rnti,
rrc_gNB_mui,
ctxt_pP->module_id,
DCCH);
......@@ -1713,23 +1661,19 @@ if (h_rc == HASH_TABLE_OK ) {
NULL,
NULL,
0,
ue_context_pP->ue_context.rnti,
ue_p->rnti,
cellGroupConfig);
nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, SDU_CONFIRM_NO, size, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
}
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ?
NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS;
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
: NR_RRC_RECONFIGURATION_DELAY_MS;
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
ue_context_pP->ue_context.rnti,
*RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
delay_ms);
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
}
}
//-----------------------------------------------------------------------------
......@@ -1740,8 +1684,9 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
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;
NR_CellGroupConfig_t *masterCellGroup = ue_context_pP->ue_context.masterCellGroup;
NR_CellGroupConfig_t *masterCellGroup = ue_p->masterCellGroup;
if (dl_bwp_id > 0) {
*masterCellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id = dl_bwp_id;
*masterCellGroup->spCellConfig->spCellConfigDedicated->defaultDownlinkBWP_Id = dl_bwp_id;
......@@ -1769,17 +1714,8 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
masterCellGroup);
gNB_RrcConfigurationReq *configuration = &RC.nrrrc[ctxt_pP->module_id]->configuration;
rrc_mac_config_req_gNB(ctxt_pP->module_id,
configuration->pdsch_AntennaPorts,
configuration->pusch_AntennaPorts,
configuration->sib1_tda,
configuration->minRXTXTIME,
NULL,
NULL,
NULL,
0,
ue_context_pP->ue_context.rnti,
masterCellGroup);
rrc_mac_config_req_gNB(
ctxt_pP->module_id, configuration->pdsch_AntennaPorts, configuration->pusch_AntennaPorts, configuration->sib1_tda, configuration->minRXTXTIME, NULL, NULL, NULL, 0, ue_p->rnti, masterCellGroup);
nr_rrc_data_req(ctxt_pP,
DCCH,
......@@ -1790,16 +1726,12 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP
PDCP_TRANSMISSION_MODE_CONTROL);
if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated &&
ue_context_pP->ue_context.masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList ?
NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_RECONFIGURATION_DELAY_MS;
uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig && ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated
&& ue_p->masterCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
? NR_RRC_RECONFIGURATION_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS
: NR_RRC_RECONFIGURATION_DELAY_MS;
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id,
ue_context_pP->ue_context.rnti,
*RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing,
delay_ms);
nr_mac_enable_ue_rrc_processing_timer(ctxt_pP->module_id, ue_p->rnti, *RC.nrrrc[ctxt_pP->module_id]->carrier.servingcellconfigcommon->ssbSubcarrierSpacing, delay_ms);
}
return 0;
......@@ -1814,12 +1746,10 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
{
module_id_t Idx;
asn_dec_rval_t dec_rval;
NR_UL_CCCH_Message_t *ul_ccch_msg = NULL;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
NR_UL_CCCH_Message_t *ul_ccch_msg = NULL;
gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id];
NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL;
NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest;
uint64_t random_value = 0;
NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest;
LOG_I(NR_RRC, "Decoding CCCH: RNTI %04lx, inst %ld, payload_size %d\n", ctxt_pP->rntiMaybeUEid, ctxt_pP->instance, buffer_length);
dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0);
......@@ -1842,7 +1772,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest:
LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %lx)\n", ctxt_pP->rntiMaybeUEid);
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(gnb_rrc_inst, ctxt_pP->rntiMaybeUEid);
if (ue_context_p != NULL) {
rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p);
} else {
......@@ -1854,7 +1784,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
(long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size);
return -1;
}
uint64_t random_value = 0;
memcpy(((uint8_t *) & random_value) + 3,
rrcSetupRequest->ue_Identity.choice.randomValue.buf,
rrcSetupRequest->ue_Identity.choice.randomValue.size);
......@@ -1899,7 +1829,6 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
/* for that, remove the context from the RB tree */
RB_REMOVE(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
/* and insert again, after changing rnti everywhere it has to be changed */
ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid;
ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid;
RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p);
/* reset timers */
......@@ -1925,6 +1854,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
}
} else {
/* TODO */
uint64_t random_value = 0;
memcpy(((uint8_t *) & random_value) + 3,
rrcSetupRequest->ue_Identity.choice.randomValue.buf,
rrcSetupRequest->ue_Identity.choice.randomValue.size);
......@@ -2161,7 +2091,7 @@ rrc_gNB_decode_dcch(
{
asn_dec_rval_t dec_rval;
NR_UL_DCCH_Message_t *ul_dcch_msg = NULL;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
rrc_gNB_ue_context_t *ue_context_p = NULL;
uint8_t xid;
int i;
......@@ -2821,7 +2751,7 @@ static int rrc_process_DU_DL(MessageDef *msg_p, instance_t instance)
NRDuDlReq_t * req=&NRDuDlReq(msg_p);
protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
if (req->srb_id == 0) {
AssertFatal(0 == 1, "should pass through dl_rrc_message()\n");
......@@ -3011,7 +2941,7 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, instance_
protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id];
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
MessageDef *message_p;
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_RESP);
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p);
......@@ -3240,7 +3170,7 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, in
protocol_ctxt_t ctxt = {.rntiMaybeUEid = req->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id];
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
MessageDef *message_p;
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP);
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p);
......@@ -3389,7 +3319,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
NR_CellGroupConfig_t *cellGroupConfig = NULL;
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
......@@ -3444,7 +3374,7 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
protocol_ctxt_t ctxt = {.rntiMaybeUEid = resp->rnti, .module_id = instance, .instance = instance, .enb_flag = 1, .eNB_index = instance};
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rntiMaybeUEid);
e1ap_bearer_setup_req_t req = {0};
req.numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions;
......@@ -3675,7 +3605,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
MessageDef *msg;
rrc_gNB_ue_context_t *ue_context_p = NULL;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) {
ctxt_pP->rntiMaybeUEid = ue_context_p->ue_id_rnti;
ctxt_pP->rntiMaybeUEid = ue_context_p->ue_context.rnti;
gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!!
if (ue_context_p->ue_context.ul_failure_timer > 0) {
......@@ -3821,7 +3751,7 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex
void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) {
// Find the UE context from UE ID and send ITTI message to F1AP to send UE context modification message to DU
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, resp->gNB_cu_cp_ue_id);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], resp->gNB_cu_cp_ue_id);
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);
......@@ -3874,9 +3804,10 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc)
rrc_gNB_ue_context_t *ue_context_p = NULL;
/* cast is necessary to eliminate warning "discards ‘const’ qualifier" */
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head) {
const rnti_t rnti = ue_context_p->ue_id_rnti;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &((gNB_RRC_INST *)rrc)->rrc_ue_head)
{
const gNB_RRC_UE_t *ue_ctxt = &ue_context_p->ue_context;
const rnti_t rnti = ue_ctxt->rnti;
fprintf(f, "NR RRC UE rnti %04x:", rnti);
......@@ -3991,7 +3922,7 @@ void *rrc_gnb_task(void *args_p) {
/* Messages from gNB app */
case NRRRC_CONFIGURATION_REQ:
openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p));
openair_rrc_gNB_configuration(instance, &NRRRC_CONFIGURATION_REQ(msg_p));
break;
/* Messages from F1AP task */
......@@ -4028,7 +3959,7 @@ void *rrc_gnb_task(void *args_p) {
/* Messages from X2AP */
case X2AP_ENDC_SGNB_ADDITION_REQ:
LOG_I(NR_RRC, "Received ENDC sgNB addition request from X2AP \n");
rrc_gNB_process_AdditionRequestInformation(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p));
rrc_gNB_process_AdditionRequestInformation(instance, &X2AP_ENDC_SGNB_ADDITION_REQ(msg_p));
break;
case X2AP_ENDC_SGNB_RECONF_COMPLETE:
......@@ -4041,11 +3972,11 @@ void *rrc_gnb_task(void *args_p) {
case X2AP_ENDC_SGNB_RELEASE_REQUEST:
LOG_I(NR_RRC, "Received ENDC sgNB release request from X2AP \n");
rrc_gNB_process_release_request(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p));
rrc_gNB_process_release_request(instance, &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p));
break;
case X2AP_ENDC_DC_OVERALL_TIMEOUT:
rrc_gNB_process_dc_overall_timeout(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p));
rrc_gNB_process_dc_overall_timeout(instance, &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p));
break;
case NGAP_UE_CONTEXT_RELEASE_REQ:
......@@ -4088,15 +4019,11 @@ rrc_gNB_generate_SecurityModeCommand(
{
uint8_t buffer[100];
uint8_t size;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
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));
NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_context_pP->ue_context.integrity_algorithm;
size = do_NR_SecurityModeCommand(
ctxt_pP,
buffer,
rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id),
ue_context_pP->ue_context.ciphering_algorithm,
&integrity_algorithm);
NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm;
size = do_NR_SecurityModeCommand(ctxt_pP, buffer, rrc_gNB_get_next_transaction_identifier(ctxt_pP->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,
PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n",
......@@ -4107,8 +4034,8 @@ rrc_gNB_generate_SecurityModeCommand(
case ngran_gNB_CU:
case ngran_gNB_CUCP:
// create an ITTI message
memcpy(ue_context_pP->ue_context.Srb[1].Srb_info.Tx_buffer.Payload, buffer, size);
ue_context_pP->ue_context.Srb[1].Srb_info.Tx_buffer.payload_size = size;
memcpy(ue_p->Srb[1].Srb_info.Tx_buffer.Payload, buffer, size);
ue_p->Srb[1].Srb_info.Tx_buffer.payload_size = size;
LOG_I(NR_RRC,"calling rrc_data_req :securityModeCommand\n");
nr_rrc_data_req(ctxt_pP,
......@@ -4220,10 +4147,12 @@ rrc_gNB_generate_RRCRelease(
{
uint8_t buffer[RRC_BUF_SIZE] = {0};
int size = do_NR_RRCRelease(buffer, RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id));
ue_context_pP->ue_context.ue_reestablishment_timer = 0;
ue_context_pP->ue_context.ue_release_timer = 0;
ue_context_pP->ue_context.ul_failure_timer = 0;
ue_context_pP->ue_context.ue_release_timer_rrc = 0;
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
ue_p->ue_reestablishment_timer = 0;
ue_p->ue_release_timer = 0;
ue_p->ul_failure_timer = 0;
ue_p->ue_release_timer_rrc = 0;
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),
......@@ -4254,8 +4183,8 @@ rrc_gNB_generate_RRCRelease(
buffer,
PDCP_TRANSMISSION_MODE_CONTROL);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id);
ue_context_pP->ue_context.ue_release_timer_rrc = 1;
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_p->gNB_ue_ngap_id);
ue_p->ue_release_timer_rrc = 1;
}
}
......
......@@ -44,68 +44,64 @@
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 i;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
if (create_tunnel_resp_pP) {
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);
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
for (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];
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]],
inde_list[i],
i,
create_tunnel_resp_pP->eps_bearer_id[i],
create_tunnel_resp_pP->enb_addr.length);
}
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)
{
if (!create_tunnel_resp_pP) {
LOG_E(NR_RRC, "create_tunnel_resp_pP error\n");
return -1;
}
return 0;
} else {
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);
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.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];
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]],
inde_list[i],
i,
create_tunnel_resp_pP->eps_bearer_id[i],
create_tunnel_resp_pP->enb_addr.length);
}
return 0;
}
int nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t *const ctxt_pP, const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, int offset)
{
int i;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
if (create_tunnel_resp_pP) {
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
create_tunnel_resp_pP->num_tunnels);
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rntiMaybeUEid);
for (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];
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_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);
}
if (!create_tunnel_resp_pP) {
LOG_E(NR_RRC, "create_tunnel_resp_pP error\n");
return -1;
}
return 0;
} else {
LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT " RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels);
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.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];
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_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);
}
return 0;
}
......@@ -67,6 +67,7 @@
#include "NGAP_QosFlowAddOrModifyRequestItem.h"
#include "NGAP_NonDynamic5QIDescriptor.h"
#include "conversions.h"
#include "RRC/NR/rrc_gNB_radio_bearers.h"
extern RAN_CONTEXT_t RC;
/* Masks for NGAP Encryption algorithms, NEA0 is always supported (not coded) */
......@@ -81,31 +82,8 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000;
#define INTEGRITY_ALGORITHM_NONE NR_IntegrityProtAlgorithm_nia0
typedef struct pdusession_tobe_added_s {
/* Unique pdusession_id for the UE. */
uint8_t pdusession_id;
/* Unique drb_ID for the UE. */
uint8_t drb_ID;
/* The transport layer address for the IP packets */
ngap_transport_layer_addr_t upf_addr;
/* S-GW Tunnel endpoint identifier */
uint32_t gtp_teid;
int nb_qos;
/* Quality of service for this pdusession */
} pdusession_tobe_added_t;
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);
//------------------------------------------------------------------------------
struct rrc_gNB_ue_context_s *rrc_gNB_get_ue_context_from_ngap_ids(instance_t instanceP, const uint32_t gNB_ue_ngap_id)
//------------------------------------------------------------------------------
{
return rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], gNB_ue_ngap_id);
}
/*! \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.
......@@ -275,14 +253,38 @@ rrc_gNB_send_NGAP_NAS_FIRST_REQ(
itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p);
}
int decodePDUSessionResourceSetup(ngap_pdu_t *pdu)
static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session)
{
DevAssert(qos->list.count > 0);
DevAssert(qos->list.count <= NGAP_maxnoofQosFlows);
for (int qosIdx = 0; qosIdx < qos->list.count; qosIdx++) {
NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p = qos->list.array[qosIdx];
// Set the QOS informations
session->qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
NGAP_QosCharacteristics_t *qosChar = &qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics;
if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
if (qosChar->choice.nonDynamic5QI != NULL) {
session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI;
}
}
ngap_allocation_retention_priority_t *tmp = &session->qos[qosIdx].allocation_retention_priority;
NGAP_AllocationAndRetentionPriority_t *tmp2 = &qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority;
tmp->priority_level = tmp2->priorityLevelARP;
tmp->pre_emp_capability = tmp2->pre_emptionCapability;
tmp->pre_emp_vulnerability = tmp2->pre_emptionVulnerability;
}
session->nb_qos = qos->list.count;
}
static int decodePDUSessionResourceSetup(pdusession_t *session)
{
NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer;
pdusession_tobe_added_t PduSession[NGAP_MAX_PDUSESSION];
asn_dec_rval_t dec_rval = aper_decode(NULL, &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, (void **)&pdusessionTransfer, pdu->buffer, pdu->length, 0, 0);
asn_dec_rval_t dec_rval =
aper_decode(NULL, &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, (void **)&pdusessionTransfer, session->pdusessionTransfer.buffer, session->pdusessionTransfer.length, 0, 0);
if (dec_rval.code != RC_OK) {
LOG_E(NR_RRC, "could not decode PDUSessionResourceSetupRequestTransfer\n");
LOG_E(NR_RRC, "can not decode PDUSessionResourceSetupRequestTransfer\n");
return -1;
}
......@@ -298,12 +300,12 @@ int decodePDUSessionResourceSetup(ngap_pdu_t *pdu)
NGAP_GTPTunnel_t *gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel;
/* Set the transport layer address */
memcpy(PduSession[i].upf_addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size);
memcpy(session->upf_addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size);
PduSession[i].upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
session->upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
/* GTP tunnel endpoint ID */
OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, PduSession[i].gtp_teid);
OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, session->gtp_teid);
}
break;
......@@ -318,7 +320,7 @@ int decodePDUSessionResourceSetup(ngap_pdu_t *pdu)
/* mandatory PDUSessionType */
case NGAP_ProtocolIE_ID_id_PDUSessionType:
PduSession[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType;
session->upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType;
break;
/* optional SecurityIndication */
......@@ -330,34 +332,9 @@ int decodePDUSessionResourceSetup(ngap_pdu_t *pdu)
break;
/* mandatory QosFlowSetupRequestList */
case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList: {
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows);
PduSession[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count;
for (int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++) {
NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx];
/*
// Set the QOS informations
PduSession[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){
PduSession[i].qos[qosIdx].fiveQI =
(uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI;
}
}
ngap_allocation_retention_priority_t *tmp=& PduSession[i].qos[qosIdx].allocation_retention_priority;
NGAP_AllocationAndRetentionPriority_t *tmp2=&qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority;
tmp->priority_level = tmp2->priorityLevelARP;
tmp->pre_emp_capability = tmp2->pre_emptionCapability;
tmp->pre_emp_vulnerability = tmp2->pre_emptionVulnerability;
*/
}
}
break;
case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList:
fill_qos(&pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList, session);
break;
/* optional CommonNetworkInstance */
case NGAP_ProtocolIE_ID_id_CommonNetworkInstance:
......@@ -378,7 +355,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
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_from_ngap_ids(instance, req->gNB_ue_ngap_id);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if (ue_context_p == NULL) {
......@@ -394,35 +371,28 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
UE->amf_ue_ngap_id = req->amf_ue_ngap_id;
uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions;
if (nb_pdusessions_tosetup != 0) {
if (nb_pdusessions_tosetup) {
AssertFatal(false, "PDU sessions in Initial context setup request not handled by E1 yet\n");
/*
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0};
for (int i = 0; i < nb_pdusessions_tosetup; i++) {
UE->nb_of_pdusessions++;
if(UE->pduSession[i].status >= PDU_SESSION_STATUS_DONE)
continue;
continue;
UE->pduSession[i].status = PDU_SESSION_STATUS_NEW;
UE->pduSession[i].param = req->pdusession_param[pdu_sessions_done];
create_tunnel_req.pdusession_id[pdu_sessions_done] = req->pdusession_param[pdu_sessions_done].pdusession_id;
create_tunnel_req.outgoing_teid[pdu_sessions_done] = req->pdusession_param[pdu_sessions_done].gtp_teid;
// To be developped: hardcoded first flow
create_tunnel_req.outgoing_qfi[pdu_sessions_done] = req->pdusession_param[pdu_sessions_done].qos[0].qfi;
create_tunnel_req.dst_addr[pdu_sessions_done].length = req->pdusession_param[pdu_sessions_done].upf_addr.length;
memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, req->pdusession_param[pdu_sessions_done].upf_addr.buffer, sizeof(uint8_t) * 20);
LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[pdu_sessions_done], create_tunnel_req.pdusession_id[pdu_sessions_done]);
pdu_sessions_done++;
if(pdu_sessions_done >= nb_pdusessions_tosetup) {
break;
}
}
UE->nbPduSessions = req->nb_of_pdusessions;
create_tunnel_req.ue_id = UE->rnti;
create_tunnel_req.num_tunnels = pdu_sessions_done;
ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp);
if (ret != 0) {
UE->pduSession[i].param = req->pdusession_param[i];
create_tunnel_req.num_tunnels++;
create_tunnel_req.pdusession_id[i] = req->pdusession_param[i].pdusession_id;
create_tunnel_req.outgoing_teid[i] = req->pdusession_param[i].gtp_teid;
// To be developped: hardcoded first flow
create_tunnel_req.outgoing_qfi[i] = req->pdusession_param[i].qos[0].qfi;
create_tunnel_req.dst_addr[i].length = req->pdusession_param[i].upf_addr.length;
memcpy(create_tunnel_req.dst_addr[i].buffer, req->pdusession_param[i].upf_addr.buffer, sizeof(create_tunnel_req.dst_addr[i].buffer));
LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, create_tunnel_req.outgoing_teid[i], create_tunnel_req.pdusession_id[i]);
}
create_tunnel_req.ue_id = UE->rnti;
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp = {0};
int ret = gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, &create_tunnel_resp);
if (ret != 0) {
LOG_E(NR_RRC, "rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n", UE->rnti);
UE->ue_release_timer_ng = 1;
UE->ue_release_timer_thres_ng = 100;
......@@ -430,13 +400,11 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
UE->ue_reestablishment_timer = 0;
UE->ul_failure_timer = 20000;
UE->ul_failure_timer = 0;
return (0);
}
return (0);
}
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0);
UE->nbPduSessions += req->nb_of_pdusessions;
UE->established_pdu_sessions_flag = 1;
*/
nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(&ctxt, &create_tunnel_resp, 0);
UE->established_pdu_sessions_flag = 1;
}
/* NAS PDU */
......@@ -474,16 +442,14 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(const protocol_ctxt_t *const c
resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
for (int pdusession = 0; pdusession < sizeofArray(UE->pduSession); pdusession++) {
for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) {
rrc_pdu_session_param_t *session = &UE->pduSession[pdusession];
if (session->status == PDU_SESSION_STATUS_DONE) {
pdu_sessions_done++;
resp->pdusessions[pdusession].pdusession_id = pdusession;
// TODO add other information from S1-U when it will be integrated
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;
// FIXXX
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;
......@@ -624,10 +590,9 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
{
uint32_t length;
uint8_t *buffer;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
protocol_ctxt_t ctxt = {0};
ngap_downlink_nas_t *req = &NGAP_DOWNLINK_NAS(msg_p);
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, req->gNB_ue_ngap_id);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], req->gNB_ue_ngap_id);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if (ue_context_p == NULL) {
......@@ -635,49 +600,45 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu
MessageDef *msg_fail_p;
LOG_W(NR_RRC, "[gNB %ld] In NGAP_DOWNLINK_NAS: unknown UE from NGAP ids (%u)\n", instance, req->gNB_ue_ngap_id);
msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_NON_DELIVERY_IND);
NGAP_NAS_NON_DELIVERY_IND(msg_fail_p).gNB_ue_ngap_id = req->gNB_ue_ngap_id;
NGAP_NAS_NON_DELIVERY_IND(msg_fail_p).nas_pdu.length = req->nas_pdu.length;
NGAP_NAS_NON_DELIVERY_IND(msg_fail_p).nas_pdu.buffer = req->nas_pdu.buffer;
ngap_nas_non_delivery_ind_t *msg = &NGAP_NAS_NON_DELIVERY_IND(msg_fail_p);
msg->gNB_ue_ngap_id = req->gNB_ue_ngap_id;
msg->nas_pdu.length = req->nas_pdu.length;
msg->nas_pdu.buffer = req->nas_pdu.buffer;
// TODO add failure cause when defined!
itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p);
return (-1);
} else {
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
}
/* Is it the first income from NGAP ? */
if (UE->gNB_ue_ngap_id == 0) {
UE->gNB_ue_ngap_id = NGAP_DOWNLINK_NAS(msg_p).gNB_ue_ngap_id;
}
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
/* Create message for PDCP (DLInformationTransfer_t) */
length = do_NR_DLInformationTransfer(instance, &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.
*/
switch (RC.nrrrc[ctxt.module_id]->node_type) {
case ngran_gNB_CU:
case ngran_gNB_CUCP:
case ngran_gNB: {
long srb_id;
if (UE->Srb[2].Active)
srb_id = UE->Srb[2].Srb_info.Srb_id;
else
srb_id = UE->Srb[1].Srb_info.Srb_id;
AssertFatal(srb_id > 0 && srb_id < maxSRBs, "");
/* Transfer data to PDCP */
nr_rrc_data_req(&ctxt, srb_id, (*rrc_gNB_mui)++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
} break;
case ngran_gNB_DU:
// nothing to do for DU
break;
/* Create message for PDCP (DLInformationTransfer_t) */
length = do_NR_DLInformationTransfer(instance, &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.
*/
switch (RC.nrrrc[ctxt.module_id]->node_type) {
case ngran_gNB_CU:
case ngran_gNB_CUCP:
case ngran_gNB: {
long srb_id;
if (UE->Srb[2].Active)
srb_id = UE->Srb[2].Srb_info.Srb_id;
else
srb_id = UE->Srb[1].Srb_info.Srb_id;
AssertFatal(srb_id > 0 && srb_id < maxSRBs, "");
/* Transfer data to PDCP */
nr_rrc_data_req(&ctxt, srb_id, (*rrc_gNB_mui)++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL);
} break;
case ngran_gNB_DU:
// nothing to do for DU
break;
default:
LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt.module_id]->node_type);
}
return (0);
default:
LOG_W(NR_RRC, "Unknown node type %d\n", RC.nrrrc[ctxt.module_id]->node_type);
}
return (0);
}
//------------------------------------------------------------------------------
......@@ -728,13 +689,11 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
gNB_RRC_UE_t *UE = &ue_context_pP->ue_context;
resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
for (int pdusession = 0; pdusession < sizeofArray(UE->pduSession); pdusession++) {
for (int pdusession = 0; pdusession < UE->nb_of_pdusessions; pdusession++) {
rrc_pdu_session_param_t *session = &UE->pduSession[pdusession];
if (session->status == PDU_SESSION_STATUS_DONE) {
pdusession_setup_t *tmp = &resp->pdusessions[pdu_sessions_done];
tmp->pdusession_id = session->param.pdusession_id;
// FIXXX
tmp->pdusession_id = 1;
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;
......@@ -791,7 +750,7 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
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_from_ngap_ids(instance, msg->gNB_ue_ngap_id);
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];
......@@ -812,15 +771,12 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
e1ap_bearer_setup_req_t bearer_req = {0};
for (int i = 0; i < msg->nb_pdusessions_tosetup; i++) {
int idx = -1;
for (int j = 0; j < UE->nb_of_pdusessions; j++)
if (msg->pdusession_setup_params[i].pdusession_id == UE->pduSession[j].param.pdusession_id) {
idx = j;
break;
}
if (idx == -1)
idx = UE->nb_of_pdusessions++;
rrc_pdu_session_param_t *pduSession = find_pduSession(UE, msg->pdusession_setup_params[i].pdusession_id, true);
pdusession_t *session = &pduSession->param;
session->pdusession_id = msg->pdusession_setup_params[i].pdusession_id;
session->nas_pdu = msg->pdusession_setup_params[i].nas_pdu;
session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer;
decodePDUSessionResourceSetup(session);
bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id;
bearer_req.rnti = UE->rnti;
bearer_req.cipheringAlgorithm = UE->ciphering_algorithm;
......@@ -828,24 +784,15 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
bearer_req.integrityProtectionAlgorithm = UE->integrity_algorithm;
memcpy(bearer_req.integrityProtectionKey, UE->kgnb, sizeof(UE->kgnb));
bearer_req.ueDlAggMaxBitRate = msg->ueAggMaxBitRateDownlink;
pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions;
bearer_req.numPDUSessions++;
UE->pduSession[idx].nas_pdu = msg->pdusession_setup_params[i].nas_pdu;
UE->pduSession[idx].pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer;
pdu_session_to_setup_t *pdu = bearer_req.pduSession + i;
pdu->sessionId = msg->pdusession_setup_params[i].pdusession_id;
pdu->sessionType = msg->pdusession_setup_params[i].upf_addr.pdu_session_type;
pdu->sst = msg->allowed_nssai[i].sST;
pdu->sessionId = session->pdusession_id;
pdu->sst = msg->allowed_nssai[i].sST;
pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
pdu->teId = msg->pdusession_setup_params[i].gtp_teid;
memcpy(&pdu->tlAddress,
msg->pdusession_setup_params[i].upf_addr.buffer,
sizeof(uint8_t)*4);
UE->pduSession[idx].param = msg->pdusession_setup_params[i];
pdu->teId = session->gtp_teid;
memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
for (int j=0; j < pdu->numDRB2Setup; j++) {
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
......@@ -872,31 +819,55 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
cellGroup->id = 0; // MCG
}
drb->numQosFlow2Setup = msg->pdusession_setup_params[i].nb_qos;
drb->numQosFlow2Setup = session->nb_qos;
for (int k=0; k < drb->numQosFlow2Setup; k++) {
qos_flow_to_setup_t *qos = drb->qosFlows + k;
qos->id = msg->pdusession_setup_params[j].qos[k].qfi;
qos->fiveQI = msg->pdusession_setup_params[j].qos[k].fiveQI;
qos->fiveQI_type = msg->pdusession_setup_params[j].qos[k].fiveQI_type;
qos->id = session->qos[k].qfi;
qos->fiveQI = session->qos[k].fiveQI;
qos->fiveQI_type = session->qos[k].fiveQI_type;
qos->qoSPriorityLevel = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level;
qos->pre_emptionCapability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability;
qos->pre_emptionVulnerability = msg->pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability;
qos->qoSPriorityLevel = session->qos[k].allocation_retention_priority.priority_level;
qos->pre_emptionCapability = session->qos[k].allocation_retention_priority.pre_emp_capability;
qos->pre_emptionVulnerability = session->qos[k].allocation_retention_priority.pre_emp_vulnerability;
}
}
}
rrc->cucp_cuup.bearer_context_setup(&bearer_req, instance);
return;
}
void for_modify(ngap_pdu_t *pdu)
static void fill_qos2(NGAP_QosFlowAddOrModifyRequestList_t *qos, pdusession_t *session)
{
NGAP_PDUSessionResourceModifyRequestTransfer_t *pdusessionTransfer;
pdusession_tobe_added_t PduSession[NGAP_MAX_PDUSESSION];
// we need to duplicate the function fill_qos because all data types are slightly different
DevAssert(qos->list.count > 0);
DevAssert(qos->list.count <= NGAP_maxnoofQosFlows);
for (int qosIdx = 0; qosIdx < qos->list.count; qosIdx++) {
NGAP_QosFlowAddOrModifyRequestItem_t *qosFlowItem_p = qos->list.array[qosIdx];
// Set the QOS informations
session->qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
NGAP_QosCharacteristics_t *qosChar = &qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics;
if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
if (qosChar->choice.nonDynamic5QI != NULL) {
session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI;
}
} else if (qosChar->present == NGAP_QosCharacteristics_PR_dynamic5QI) {
// TODO
}
asn_dec_rval_t dec_rval = aper_decode(NULL, &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, (void **)&pdusessionTransfer, pdu->buffer, pdu->length, 0, 0);
ngap_allocation_retention_priority_t *tmp = &session->qos[qosIdx].allocation_retention_priority;
NGAP_AllocationAndRetentionPriority_t *tmp2 = &qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority;
tmp->priority_level = tmp2->priorityLevelARP;
tmp->pre_emp_capability = tmp2->pre_emptionCapability;
tmp->pre_emp_vulnerability = tmp2->pre_emptionVulnerability;
}
session->nb_qos = qos->list.count;
}
static void decodePDUSessionResourceModify(pdusession_t *param, const ngap_pdu_t pdu)
{
NGAP_PDUSessionResourceModifyRequestTransfer_t *pdusessionTransfer;
asn_dec_rval_t dec_rval = aper_decode(NULL, &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, (void **)&pdusessionTransfer, pdu.buffer, pdu.length, 0, 0);
if (dec_rval.code != RC_OK) {
LOG_E(NR_RRC, "could not decode PDUSessionResourceModifyRequestTransfer\n");
......@@ -925,40 +896,14 @@ void for_modify(ngap_pdu_t *pdu)
break;
/* optional QosFlowAddOrModifyRequestList */
case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList: {
NGAP_QosFlowAddOrModifyRequestItem_t *qosFlowItem_p;
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count > 0);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count <= NGAP_maxnoofQosFlows);
PduSession[j].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count;
for (int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; qosIdx++) {
/*
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.array[qosIdx];
// Set the QOS informations
PduSession[j].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
if(qosFlowItem_p->qosFlowLevelQosParameters) {
if (qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
PduSession[j].qos[qosIdx].fiveQI =
qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.choice.nonDynamic5QI->fiveQI;
} else if (qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics.present == NGAP_QosCharacteristics_PR_dynamic5QI) {
// TODO
}
ngap_allocation_retention_priority_t *tmp=& PduSession[j].qos[qosIdx].allocation_retention_priority;
NGAP_AllocationAndRetentionPriority_t *tmp2=&qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority;
tmp->priority_level = tmp2->priorityLevelARP;
tmp->pre_emp_capability = tmp2->pre_emptionCapability;
tmp->pre_emp_vulnerability = tmp2->pre_emptionVulnerability;
}
*/
}
} break;
case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList:
fill_qos2(&pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList, param);
break;
/* optional QosFlowToReleaseList */
case NGAP_ProtocolIE_ID_id_QosFlowToReleaseList:
// TODO
LOG_E(NR_RRC, "Cant' handle NGAP_ProtocolIE_ID_id_QosFlowToReleaseList\n");
LOG_E(NR_RRC, "Can't handle NGAP_ProtocolIE_ID_id_QosFlowToReleaseList\n");
break;
/* optional AdditionalUL-NGU-UP-TNLInformation */
......@@ -984,128 +929,86 @@ void for_modify(ngap_pdu_t *pdu)
int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
{
uint8_t nb_pdusessions_tomodify;
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);
nb_pdusessions_tomodify = req->nb_pdusessions_tomodify;
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, req->gNB_ue_ngap_id);
ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], 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);
} else {
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;
bool is_treated[NGAP_MAX_PDUSESSION] = {false};
uint8_t nb_of_failed_pdusessions = 0;
for (int i = 0; i < nb_pdusessions_tomodify; i++) {
// pdu_session_param_t *session=&UE->pduSession[i];
if (is_treated[i] == true) {
continue;
}
// Check if same PDU session ID to handle multiple pdu sessions
for (int j = i + 1; j < nb_pdusessions_tomodify; j++) {
if (is_treated[j] == false && req->pdusession_modify_params[j].pdusession_id == req->pdusession_modify_params[i].pdusession_id) {
// 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[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances;
nb_of_failed_pdusessions++;
is_treated[i] = true;
is_treated[j] = true;
}
}
// handle multiple pdu session id case
if (is_treated[i] == true) {
LOG_D(NR_RRC, "handle multiple pdu session id \n");
UE->modify_pdusession[i].status = PDU_SESSION_STATUS_NEW;
UE->modify_pdusession[i].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id;
UE->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances;
nb_of_failed_pdusessions++;
continue;
}
// Check pdu session ID is established
for (int j = 0; j < NR_NB_RB_MAX - 3; j++) {
if (UE->pduSession[j].param.pdusession_id == req->pdusession_modify_params[i].pdusession_id) {
if (UE->pduSession[j].status == PDU_SESSION_STATUS_TORELEASE || UE->pduSession[j].status == PDU_SESSION_STATUS_DONE) {
break;
}
// Found established pdu session, prepare to send RRC message
UE->modify_pdusession[i].status = PDU_SESSION_STATUS_NEW;
UE->modify_pdusession[i].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id;
UE->modify_pdusession[i].cause = NGAP_CAUSE_NOTHING;
if (NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].nas_pdu.buffer != NULL) {
UE->modify_pdusession[i].param.nas_pdu = req->pdusession_modify_params[i].nas_pdu;
}
// Save new pdu session parameters, qos, upf addr, teid
for (int qos_flow_index = 0; qos_flow_index < req->pdusession_modify_params[i].nb_qos; qos_flow_index++) {
UE->modify_pdusession[i].param.qos[qos_flow_index] = req->pdusession_modify_params[i].qos[qos_flow_index];
}
UE->modify_pdusession[i].param.nb_qos = req->pdusession_modify_params[i].nb_qos;
UE->modify_pdusession[i].param.upf_addr = UE->pduSession[j].param.upf_addr;
UE->modify_pdusession[i].param.gtp_teid = UE->pduSession[j].param.gtp_teid;
is_treated[i] = true;
break;
}
}
}
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;
// handle Unknown pdu session ID
if (is_treated[i] == false) {
LOG_D(NR_RRC, "handle Unknown pdu session ID \n");
UE->modify_pdusession[i].status = PDU_SESSION_STATUS_NEW;
UE->modify_pdusession[i].param.pdusession_id = req->pdusession_modify_params[i].pdusession_id;
UE->modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK;
UE->modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID;
nb_of_failed_pdusessions++;
is_treated[i] = 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)
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++;
} 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;
}
// 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;
}
}
UE->nb_of_modify_pdusessions = nb_pdusessions_tomodify;
UE->nb_of_failed_pdusessions = nb_of_failed_pdusessions;
if (UE->nb_of_failed_pdusessions < UE->nb_of_modify_pdusessions) {
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");
uint8_t nb_of_pdu_sessions_failed = 0;
MessageDef *msg_fail_p = NULL;
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);
}
ngap_pdusession_modify_resp_t *msg = &NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p);
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;
}
UE->nb_of_modify_pdusessions = req->nb_pdusessions_tomodify - nb_of_failed_pdusessions;
UE->nb_of_failed_pdusessions = nb_of_failed_pdusessions;
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);
if (UE->nb_of_failed_pdusessions < UE->nb_of_modify_pdusessions) {
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);
if (msg_fail_p == NULL) {
LOG_E(NR_RRC, "itti_alloc_new_message failed, msg_fail_p is NULL \n");
return (-1);
}
ngap_pdusession_modify_resp_t *msg = &NGAP_PDUSESSION_MODIFY_RESP(msg_fail_p);
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;
}
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;
}
......@@ -1134,54 +1037,55 @@ 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) {
if (UE->modify_pdusession[i].status == PDU_SESSION_STATUS_DONE) {
int j;
for (j = 0; j < UE->nb_of_pdusessions; j++) {
if (UE->modify_pdusession[i].param.pdusession_id == UE->pduSession[j].param.pdusession_id) {
LOG_I(NR_RRC, "update pdu session %d \n", UE->pduSession[j].param.pdusession_id);
// Update UE->pduSession
UE->pduSession[j].status = PDU_SESSION_STATUS_ESTABLISHED;
UE->pduSession[j].cause = NGAP_CAUSE_NOTHING;
for (int qos_flow_index = 0; qos_flow_index < UE->modify_pdusession[i].param.nb_qos; qos_flow_index++) {
UE->pduSession[j].param.qos[qos_flow_index] = UE->modify_pdusession[i].param.qos[qos_flow_index];
}
break;
}
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);
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 (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];
}
if (j < UE->nb_of_pdusessions) {
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].nb_of_qos_flow = UE->modify_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 ",
pdu_sessions_done,
i,
UE->modify_pdusession[i].status,
xid,
UE->nb_of_modify_pdusessions,
resp->pdusessions[pdu_sessions_done].pdusession_id);
pdu_sessions_done++;
} else {
resp->pdusessions_failed[pdu_sessions_failed].pdusession_id = UE->modify_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++;
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;
}
} else if ((UE->modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || (UE->modify_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[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;
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 ",
pdu_sessions_done,
i,
UE->modify_pdusession[i].status,
xid,
UE->nb_of_modify_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;
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;
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 {
LOG_D(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);
} else if ((UE->modify_pdusession[i].status == PDU_SESSION_STATUS_NEW) || (UE->modify_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;
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);
}
resp->nb_of_pdusessions = pdu_sessions_done;
......@@ -1214,8 +1118,8 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, con
req->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
req->cause = causeP;
req->cause_value = cause_valueP;
for (int i = 0; i < sizeofArray(UE->pduSession); i++) {
req->pdusessions[i].pdusession_id = i;
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
req->pdusessions[i].pdusession_id = UE->pduSession[i].param.pdusession_id;
req->nb_of_pdusessions++;
}
itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg);
......@@ -1225,9 +1129,8 @@ void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(const module_id_t gnb_mod_idP, con
int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t instance)
{
uint32_t gNB_ue_ngap_id;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_REQ(msg_p).gNB_ue_ngap_id;
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, gNB_ue_ngap_id);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], 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! */
......@@ -1243,12 +1146,10 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in
} else {
/* TODO release context. */
/* Send the response */
{
MessageDef *msg_resp_p;
msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP);
NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p);
}
MessageDef *msg_resp_p;
msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP);
NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p);
return (0);
}
}
......@@ -1263,10 +1164,8 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
//-----------------------------------------------------------------------------
uint32_t gNB_ue_ngap_id = 0;
protocol_ctxt_t ctxt;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
struct rrc_ue_ngap_ids_s *rrc_ue_ngap_ids = NULL;
gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, gNB_ue_ngap_id);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id);
if (ue_context_p == NULL) {
/* Can not associate this message to an UE index */
......@@ -1278,15 +1177,15 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).gNB_ue_ngap_id = gNB_ue_ngap_id;
itti_send_msg_to_task(TASK_NGAP, instance, msg_complete_p);
return -1;
} else {
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
UE->ue_release_timer_ng = 0;
UE->ue_release_timer_thres_rrc = 1000;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
return 0;
}
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
UE->ue_release_timer_ng = 0;
UE->ue_release_timer_thres_rrc = 1000;
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, UE->rnti, 0, 0);
ctxt.eNB_index = 0;
rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p);
return 0;
}
void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(
......@@ -1307,41 +1206,38 @@ rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(
{
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 */
unsigned char buf[4096];
unsigned char *buf2;
NR_UERadioAccessCapabilityInformation_t rac;
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);
}
asn_enc_rval_t ret = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, buf, 4096);
if (ret.encoded == -1) abort();
memset(&rac, 0, sizeof(NR_UERadioAccessCapabilityInformation_t));
int ret = uper_encode_to_new_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, &buf);
AssertFatal(ret > 0, "fail to encode ue capabilities\n");
rac.criticalExtensions.present = NR_UERadioAccessCapabilityInformation__criticalExtensions_PR_c1;
rac.criticalExtensions.choice.c1 = calloc(1,sizeof(*rac.criticalExtensions.choice.c1));
rac.criticalExtensions.choice.c1->present = NR_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation;
rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation = calloc(1,sizeof(NR_UERadioAccessCapabilityInformation_IEs_t));
rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->ue_RadioAccessCapabilityInfo.buf = buf;
rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->ue_RadioAccessCapabilityInfo.size = (ret.encoded+7)/8;
rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->nonCriticalExtension = NULL;
asn1cCalloc(rac.criticalExtensions.choice.c1, c1);
c1->present = NR_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation;
asn1cCalloc(c1->choice.ueRadioAccessCapabilityInformation, info);
info->ue_RadioAccessCapabilityInfo.buf = buf;
info->ue_RadioAccessCapabilityInfo.size = ret;
info->nonCriticalExtension = NULL;
/* 8192 is arbitrary, should be big enough */
buf2 = malloc16(8192);
if (buf2 == NULL) abort();
ret = uper_encode_to_buffer(&asn_DEF_NR_UERadioAccessCapabilityInformation, NULL, &rac, buf2, 8192);
if (ret.encoded == -1) abort();
void *buf2 = NULL;
int encoded = uper_encode_to_new_buffer(&asn_DEF_NR_UERadioAccessCapabilityInformation, NULL, &rac, &buf2);
AssertFatal(encoded > 0, "fail to encode ue capabilities\n");
;
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);
NGAP_UE_CAPABILITIES_IND(msg_p).gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
NGAP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = (ret.encoded+7)/8;
NGAP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = buf2;
ngap_ue_cap_info_ind_t *ind = &NGAP_UE_CAPABILITIES_IND(msg_p);
memset(ind, 0, sizeof(*ind));
ind->gNB_ue_ngap_id = UE->gNB_ue_ngap_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);
LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
}
......@@ -1359,23 +1255,25 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
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);
NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p).gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
ngap_pdusession_release_resp_t *resp = &NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p);
memset(resp, 0, sizeof(*resp));
resp->gNB_ue_ngap_id = UE->gNB_ue_ngap_id;
for (int i = 0; i < NB_RB_MAX; i++) {
if (xid == UE->pduSession[i].xid) {
NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p).pdusession_release[pdu_sessions_released].pdusession_id = UE->pduSession[i].param.pdusession_id;
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));
}
}
NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_released = pdu_sessions_released;
NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p).nb_of_pdusessions_failed = UE->nb_release_of_pdusessions;
memcpy(&(NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p).pdusessions_failed[0]), &UE->pdusessions_release_failed[0], sizeof(pdusession_failed_t) * UE->nb_release_of_pdusessions);
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;
LOG_I(NR_RRC, "NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d\n", NGAP_PDUSESSION_RELEASE_RESPONSE(msg_p).gNB_ue_ngap_id, pdu_sessions_released);
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
......@@ -1385,118 +1283,88 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(
//clear release pdusessions
UE->nb_release_of_pdusessions = 0;
memset(&UE->pdusessions_release_failed[0], 0, sizeof(pdusession_failed_t) * NGAP_MAX_PDUSESSION);
memset(UE->pdusessions_release_failed, 0, sizeof(UE->pdusessions_release_failed));
}
//------------------------------------------------------------------------------
int rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(MessageDef *msg_p, instance_t instance)
//------------------------------------------------------------------------------
{
uint32_t gNB_ue_ngap_id;
rrc_gNB_ue_context_t *ue_context_p = NULL;
protocol_ctxt_t ctxt;
pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION];
uint8_t nb_pdusessions_torelease;
uint32_t gNB_ue_ngap_id;
protocol_ctxt_t ctxt;
uint8_t xid;
int i, pdusession;
uint8_t b_existed,is_existed;
uint8_t pdusession_release_drb = 0;
memcpy(&pdusession_release_params[0], &(NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).pdusession_release_params[0]),
sizeof(pdusession_release_t)*NGAP_MAX_PDUSESSION);
gNB_ue_ngap_id = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id;
nb_pdusessions_torelease = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).nb_pdusessions_torelease;
if (nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) {
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;
}
ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, gNB_ue_ngap_id);
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, gNB_ue_ngap_id);
if (ue_context_p != NULL) {
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",
NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, gNB_ue_ngap_id, nb_pdusessions_torelease);
for (pdusession = 0; pdusession < nb_pdusessions_torelease; pdusession++) {
b_existed = 0;
is_existed = 0;
for (i = pdusession-1; i >= 0; i--) {
if (pdusession_release_params[pdusession].pdusession_id == pdusession_release_params[i].pdusession_id) {
is_existed = 1;
break;
}
}
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], gNB_ue_ngap_id);
if(is_existed == 1) {
// pdusession_id is existed
continue;
}
for (i = 0; i < NR_NB_RB_MAX; i++) {
if (pdusession_release_params[pdusession].pdusession_id == UE->pduSession[i].param.pdusession_id) {
b_existed = 1;
break;
}
}
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);
return -1;
}
if(b_existed == 0) {
// no pdusession_id
LOG_I(NR_RRC, "no pdusession_id \n");
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = 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++;
} else {
if (UE->pduSession[i].status == PDU_SESSION_STATUS_FAILED) {
UE->pduSession[i].xid = xid;
continue;
} else if (UE->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED) {
LOG_I(NR_RRC, "RELEASE pdusession %d \n", i);
UE->pduSession[i].status = PDU_SESSION_STATUS_TORELEASE;
UE->pduSession[i].xid = xid;
pdusession_release_drb++;
} else {
// pdusession_id status NG
UE->pdusessions_release_failed[UE->nb_release_of_pdusessions].pdusession_id = 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++;
}
}
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 & 0x000000FFFFFFFFFF, gNB_ue_ngap_id, cmd->nb_pdusessions_torelease);
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++;
continue;
}
if (pduSession->status == PDU_SESSION_STATUS_FAILED) {
pduSession->xid = xid;
continue;
}
if (pduSession->status == PDU_SESSION_STATUS_ESTABLISHED) {
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) {
//TODO RRCReconfiguration To UE
LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n");
rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.length, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.buffer);
} else {
//gtp tunnel delete
LOG_I(NR_RRC, "gtp tunnel delete \n");
gtpv1u_gnb_delete_tunnel_req_t req={0};
req.ue_id = UE->rnti;
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;
}
if (pdusession_release_drb > 0) {
// 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");
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);
LOG_I(NR_RRC, "Send PDU Session Release Response \n");
}
} else {
LOG_E(NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u Error ue_context_p NULL \n",
NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id);
return -1;
gtpv1u_delete_ngu_tunnel(instance, &req);
// NGAP_PDUSESSION_RELEASE_RESPONSE
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
LOG_I(NR_RRC, "Send PDU Session Release Response \n");
}
return 0;
}
......
......@@ -38,15 +38,14 @@
//------------------------------------------------------------------------------
int rrc_gNB_compare_ue_rnti_id(
struct rrc_gNB_ue_context_s *c1_pP, struct rrc_gNB_ue_context_s *c2_pP)
int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t *c1_pP, rrc_gNB_ue_context_t *c2_pP)
//------------------------------------------------------------------------------
{
if (c1_pP->ue_id_rnti > c2_pP->ue_id_rnti) {
if (c1_pP->ue_context.gNB_ue_ngap_id > c2_pP->ue_context.gNB_ue_ngap_id) {
return 1;
}
if (c1_pP->ue_id_rnti < c2_pP->ue_id_rnti) {
if (c1_pP->ue_context.gNB_ue_ngap_id < c2_pP->ue_context.gNB_ue_ngap_id) {
return -1;
}
......@@ -60,22 +59,16 @@ RB_GENERATE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
//------------------------------------------------------------------------------
struct rrc_gNB_ue_context_s *
rrc_gNB_allocate_new_UE_context(
gNB_RRC_INST *rrc_instance_pP
)
rrc_gNB_ue_context_t *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP)
//------------------------------------------------------------------------------
{
struct rrc_gNB_ue_context_s *new_p;
new_p = (struct rrc_gNB_ue_context_s * )malloc(sizeof(struct rrc_gNB_ue_context_s));
rrc_gNB_ue_context_t *new_p = calloc(1, sizeof(*new_p));
if (new_p == NULL) {
LOG_E(RRC, "Cannot allocate new ue context\n");
return NULL;
}
memset(new_p, 0, sizeof(struct rrc_gNB_ue_context_s));
new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator);
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;
......@@ -89,35 +82,26 @@ rrc_gNB_allocate_new_UE_context(
//------------------------------------------------------------------------------
struct rrc_gNB_ue_context_s *
rrc_gNB_get_ue_context(
gNB_RRC_INST *rrc_instance_pP,
rnti_t rntiP)
rrc_gNB_ue_context_t *rrc_gNB_get_ue_context(gNB_RRC_INST *rrc_instance_pP, rnti_t rntiP)
//------------------------------------------------------------------------------
{
rrc_gNB_ue_context_t temp;
memset(&temp, 0, sizeof(struct rrc_gNB_ue_context_s));
rrc_gNB_ue_context_t temp = {0};
/* gNB ue rrc id = 24 bits wide */
temp.ue_id_rnti = rntiP;
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
ue_context_p = RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
temp.ue_context.rnti = rntiP;
rrc_gNB_ue_context_t *ue_context_p = RB_FIND(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
if ( ue_context_p != NULL) {
if (ue_context_p != NULL)
return ue_context_p;
} else {
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
if (ue_context_p->ue_context.rnti == rntiP) {
return ue_context_p;
}
}
return NULL;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head))
{
if (ue_context_p->ue_context.rnti == rntiP)
return ue_context_p;
}
return NULL;
}
void rrc_gNB_free_mem_UE_context(
const protocol_ctxt_t *const ctxt_pP,
struct rrc_gNB_ue_context_s *const ue_context_pP
)
void rrc_gNB_free_mem_UE_context(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
//-----------------------------------------------------------------------------
{
......@@ -133,10 +117,7 @@ void rrc_gNB_free_mem_UE_context(
}
//------------------------------------------------------------------------------
void rrc_gNB_remove_ue_context(
const protocol_ctxt_t *const ctxt_pP,
gNB_RRC_INST *rrc_instance_pP,
struct rrc_gNB_ue_context_s *ue_context_pP)
void rrc_gNB_remove_ue_context(const protocol_ctxt_t *const ctxt_pP, gNB_RRC_INST *rrc_instance_pP, rrc_gNB_ue_context_t *ue_context_pP)
//------------------------------------------------------------------------------
{
if (rrc_instance_pP == NULL) {
......@@ -153,7 +134,7 @@ void rrc_gNB_remove_ue_context(
RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP);
rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_pP);
uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid);
uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->ue_context.gNB_ue_ngap_id);
free(ue_context_pP);
rrc_instance_pP->Nb_ue --;
LOG_I(RRC,
......@@ -163,14 +144,10 @@ void rrc_gNB_remove_ue_context(
//-----------------------------------------------------------------------------
// return the ue context if there is already an UE with ue_identityP, NULL otherwise
struct rrc_gNB_ue_context_s *
rrc_gNB_ue_context_random_exist(
gNB_RRC_INST *rrc_instance_pP,
const uint64_t ue_identityP
)
rrc_gNB_ue_context_t *rrc_gNB_ue_context_random_exist(gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP)
//-----------------------------------------------------------------------------
{
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
rrc_gNB_ue_context_t *ue_context_p = NULL;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) {
if (ue_context_p->ue_context.random_ue_identity == ue_identityP)
return ue_context_p;
......@@ -180,63 +157,40 @@ rrc_gNB_ue_context_random_exist(
//-----------------------------------------------------------------------------
// return the ue context if there is already an UE with the same S-TMSI, NULL otherwise
struct rrc_gNB_ue_context_s *
rrc_gNB_ue_context_5g_s_tmsi_exist(
gNB_RRC_INST *rrc_instance_pP,
const uint64_t s_TMSI
)
rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_instance_pP, const uint64_t s_TMSI)
//-----------------------------------------------------------------------------
{
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) {
LOG_I(NR_RRC,"Checking for UE 5G S-TMSI %ld: RNTI %04x\n",
s_TMSI, ue_context_p->ue_context.rnti);
if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) {
return ue_context_p;
}
rrc_gNB_ue_context_t *ue_context_p = NULL;
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head)
{
LOG_I(NR_RRC, "Checking for UE 5G S-TMSI %ld: RNTI %04x\n", s_TMSI, ue_context_p->ue_context.rnti);
if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) {
return ue_context_p;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection
struct rrc_gNB_ue_context_s *
rrc_gNB_get_next_free_ue_context(
const protocol_ctxt_t *const ctxt_pP,
gNB_RRC_INST *rrc_instance_pP,
const uint64_t ue_identityP
)
rrc_gNB_ue_context_t *rrc_gNB_get_next_free_ue_context(const protocol_ctxt_t *const ctxt_pP, gNB_RRC_INST *rrc_instance_pP, const uint64_t ue_identityP)
//-----------------------------------------------------------------------------
{
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, ctxt_pP->rntiMaybeUEid);
if (ue_context_p == NULL) {
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc_instance_pP);
if (ue_context_p == NULL) {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, no memory\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
return NULL;
}
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, ctxt_pP->rntiMaybeUEid);
ue_context_p->ue_id_rnti = ctxt_pP->rntiMaybeUEid; // here ue_id_rnti is just a key, may be something else
ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid; // yes duplicate, 1 may be removed
ue_context_p->ue_context.random_ue_identity = ue_identityP;
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
LOG_D(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" Created new UE context uid %u\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),
ue_context_p->local_uid);
if (ue_context_p) {
LOG_E(NR_RRC, " Cannot create new UE context, already exist rnti: %lx\n", ctxt_pP->rntiMaybeUEid);
return ue_context_p;
} else {
LOG_E(NR_RRC,
PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist\n",
PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP));
return NULL;
}
return(ue_context_p);
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc_instance_pP);
if (ue_context_p == NULL)
return NULL;
ue_context_p->ue_context.rnti = ctxt_pP->rntiMaybeUEid;
ue_context_p->ue_context.random_ue_identity = ue_identityP;
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
LOG_D(NR_RRC, " Created new UE context rnti: %lx, random ue id %lx, local uid %u\n", ctxt_pP->rntiMaybeUEid, ue_identityP, ue_context_p->ue_context.gNB_ue_ngap_id);
return ue_context_p;
}
......@@ -34,52 +34,22 @@
#include "COMMON/platform_types.h"
#include "nr_rrc_defs.h"
int rrc_gNB_compare_ue_rnti_id(
struct rrc_gNB_ue_context_s* c1_pP,
struct rrc_gNB_ue_context_s* c2_pP
);
int rrc_gNB_compare_ue_rnti_id(rrc_gNB_ue_context_t* c1_pP, rrc_gNB_ue_context_t* c2_pP);
RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id);
struct rrc_gNB_ue_context_s*
rrc_gNB_allocate_new_UE_context(
gNB_RRC_INST* rrc_instance_pP
);
rrc_gNB_ue_context_t* rrc_gNB_allocate_new_UE_context(gNB_RRC_INST* rrc_instance_pP);
struct rrc_gNB_ue_context_s*
rrc_gNB_get_ue_context(
gNB_RRC_INST* rrc_instance_pP,
rnti_t rntiP
);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP);
void rrc_gNB_free_mem_UE_context(
const protocol_ctxt_t *const ctxt_pP,
struct rrc_gNB_ue_context_s *const ue_context_pP
);
void rrc_gNB_free_mem_UE_context(const protocol_ctxt_t* const ctxt_pP, rrc_gNB_ue_context_t* const ue_context_pP);
void rrc_gNB_remove_ue_context(
const protocol_ctxt_t* const ctxt_pP,
gNB_RRC_INST* rrc_instance_pP,
struct rrc_gNB_ue_context_s* ue_context_pP
);
void rrc_gNB_remove_ue_context(const protocol_ctxt_t* const ctxt_pP, gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context_t* ue_context_pP);
struct rrc_gNB_ue_context_s *
rrc_gNB_ue_context_random_exist(
gNB_RRC_INST *rrc_instance_pP,
const uint64_t ue_identityP
);
rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP);
struct rrc_gNB_ue_context_s *
rrc_gNB_ue_context_5g_s_tmsi_exist(
gNB_RRC_INST *rrc_instance_pP,
const uint64_t s_TMSI
);
rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI);
struct rrc_gNB_ue_context_s *
rrc_gNB_get_next_free_ue_context(
const protocol_ctxt_t *const ctxt_pP,
gNB_RRC_INST *rrc_instance_pP,
const uint64_t ue_identityP
);
rrc_gNB_ue_context_t* rrc_gNB_get_next_free_ue_context(const protocol_ctxt_t* const ctxt_pP, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP);
#endif
......@@ -44,9 +44,8 @@
#include "UTIL/OSA/osa_defs.h"
#include <openair2/RRC/NR/nr_rrc_proto.h>
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) {
struct rrc_gNB_ue_context_s *ue_context_p = NULL;
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)
{
OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL;
OCTET_STRING_t *ueCapabilityRAT_Container_MRDC=NULL;
asn_dec_rval_t dec_rval;
......@@ -61,36 +60,27 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
}
// decode and store capabilities
ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
if (ueCapabilityRAT_Container_nr != NULL) {
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_NR_Capability,
(void **)&ue_context_p->ue_context.UE_Capability_nr,
ueCapabilityRAT_Container_nr->buf,
ueCapabilityRAT_Container_nr->size, 0, 0);
dec_rval = uper_decode(NULL, &asn_DEF_NR_UE_NR_Capability, (void **)&UE->UE_Capability_nr, ueCapabilityRAT_Container_nr->buf, ueCapabilityRAT_Container_nr->size, 0, 0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size);
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,
ue_context_p->ue_context.UE_Capability_nr);
ue_context_p->ue_context.UE_Capability_nr = 0;
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
UE->UE_Capability_nr = 0;
AssertFatal(1==0,"exiting\n");
}
}
if (ueCapabilityRAT_Container_MRDC != NULL) {
dec_rval = uper_decode(NULL,
&asn_DEF_NR_UE_MRDC_Capability,
(void **)&ue_context_p->ue_context.UE_Capability_MRDC,
ueCapabilityRAT_Container_MRDC->buf,
ueCapabilityRAT_Container_MRDC->size, 0, 0);
dec_rval = uper_decode(NULL, &asn_DEF_NR_UE_MRDC_Capability, (void **)&UE->UE_Capability_MRDC, ueCapabilityRAT_Container_MRDC->buf, ueCapabilityRAT_Container_MRDC->size, 0, 0);
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed);
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,
ue_context_p->ue_context.UE_Capability_MRDC);
ue_context_p->ue_context.UE_Capability_MRDC = 0;
ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
UE->UE_Capability_MRDC = 0;
AssertFatal(1==0,"exiting\n");
}
}
......@@ -98,16 +88,16 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
// dump ue_capabilities
if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
}
if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC);
xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, UE->UE_Capability_MRDC);
}
LOG_A(NR_RRC, "Successfully decoded UE NR capabilities (NR and MRDC)\n");
ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = rrc->carrier.servingcellconfig;
UE->spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
UE->spCellConfig->spCellConfigDedicated = rrc->carrier.servingcellconfig;
LOG_I(NR_RRC,"Adding new NSA user (%p)\n",ue_context_p);
rrc_add_nsa_user(rrc,ue_context_p, m);
}
......@@ -116,7 +106,8 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries,
rrc_gNB_compare_ue_rnti_id);
void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) {
void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m)
{
// generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331)
rrc_gNB_carrier_data_t *carrier=&rrc->carrier;
const gNB_RrcConfigurationReq *configuration = &rrc->configuration;
......@@ -128,6 +119,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
unsigned char *kUPenc = NULL;
unsigned char *kUPint = NULL;
int i;
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
// In case of phy-test and do-ra mode, read UE capabilities directly from file
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
......@@ -149,25 +141,21 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
}
else
LOG_E(NR_RRC,"Could not open UE Capabilities input file. Not handling OAI UE Capabilities.\n");
ue_context_p->ue_context.UE_Capability_nr = UE_Capability_nr;
UE->UE_Capability_nr = UE_Capability_nr;
}
// NR RRCReconfiguration
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
ue_context_p->ue_context.secondaryCellGroup = calloc(1,sizeof(NR_CellGroupConfig_t));
memset((void *)ue_context_p->ue_context.reconfig,0,sizeof(NR_RRCReconfiguration_t));
ue_context_p->ue_context.reconfig->rrc_TransactionIdentifier=0;
ue_context_p->ue_context.reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
UE->reconfig = calloc(1, sizeof(NR_RRCReconfiguration_t));
UE->secondaryCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t));
memset((void *)UE->reconfig, 0, sizeof(NR_RRCReconfiguration_t));
UE->reconfig->rrc_TransactionIdentifier = 0;
UE->reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
UE->reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
UE->rb_config = calloc(1, sizeof(NR_RRCReconfiguration_t));
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
10 /* EPS bearer ID */,
1 /* drb ID */,
NR_CipheringAlgorithm_nea0,
NR_SecurityConfig__keyToUse_master);
fill_default_rbconfig(UE->rb_config, 10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master);
} else {
/* TODO: handle more than one bearer */
if (m == NULL) {
......@@ -180,9 +168,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
}
/* store security key and security capabilities */
memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
memcpy(UE->kgnb, m->kgnb, 32);
UE->security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
UE->security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
/* Select ciphering algorithm based on gNB configuration file and
* UE's supported algorithms.
......@@ -190,7 +178,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
* The ordering of the list comes from the configuration file.
*/
/* preset nea0 as fallback */
ue_context_p->ue_context.ciphering_algorithm = 0;
UE->ciphering_algorithm = 0;
for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) {
int nea_mask[4] = {
0,
......@@ -202,13 +190,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
/* nea0 already preselected */
break;
}
if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i];
if (UE->security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
UE->ciphering_algorithm = rrc->security.ciphering_algorithms[i];
break;
}
}
LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm);
LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)UE->ciphering_algorithm);
/* integrity: no integrity protection for DRB in ENDC mode
* as written in 38.331: "If UE is connected to E-UTRA/EPC, this field
......@@ -217,49 +205,44 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
* So nothing for DRB. Plus a test with a COTS UE revealed that it
* did not apply integrity on the DRB.
*/
ue_context_p->ue_context.integrity_algorithm = 0;
UE->integrity_algorithm = 0;
LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm);
/* derive UP security key */
nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
ue_context_p->ue_context.kgnb,
&kUPenc);
nr_derive_key_up_int(ue_context_p->ue_context.integrity_algorithm,
ue_context_p->ue_context.kgnb,
&kUPint);
nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc);
nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint);
e_NR_CipheringAlgorithm cipher_algo;
switch (ue_context_p->ue_context.ciphering_algorithm) {
case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break;
case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break;
case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break;
case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break;
default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1);
switch (UE->ciphering_algorithm) {
case 0:
cipher_algo = NR_CipheringAlgorithm_nea0;
break;
case 1:
cipher_algo = NR_CipheringAlgorithm_nea1;
break;
case 2:
cipher_algo = NR_CipheringAlgorithm_nea2;
break;
case 3:
cipher_algo = NR_CipheringAlgorithm_nea3;
break;
default:
LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
fill_default_rbconfig(ue_context_p->ue_context.rb_config,
m->e_rabs_tobeadded[0].e_rab_id,
m->e_rabs_tobeadded[0].drb_ID,
cipher_algo,
NR_SecurityConfig__keyToUse_secondary);
fill_default_rbconfig(UE->rb_config, m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID, cipher_algo, NR_SecurityConfig__keyToUse_secondary);
}
NR_ServingCellConfig_t *scc = ue_context_p->ue_context.spCellConfig ?
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated : NULL;
fill_default_reconfig(carrier->servingcellconfigcommon,
scc,
reconfig_ies,
ue_context_p->ue_context.secondaryCellGroup,
ue_context_p->ue_context.UE_Capability_nr,
configuration,
ue_context_p->local_uid);
ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
NR_ServingCellConfig_t *scc = UE->spCellConfig ? UE->spCellConfig->spCellConfigDedicated : NULL;
fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.gNB_ue_ngap_id);
ue_context_p->ue_context.rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config));
memset((void *)CG_Config,0,sizeof(*CG_Config));
//int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config);
// int CG_Config_size = generate_CG_Config(rrc,CG_Config,UE->reconfig,UE->rb_config);
generate_CG_Config(rrc, CG_Config, UE->reconfig, UE->rb_config);
if(m!=NULL) {
uint8_t inde_list[m->nb_e_rabs_tobeadded];
......@@ -267,15 +250,15 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
if (m->nb_e_rabs_tobeadded>0) {
for (int i=0; i<m->nb_e_rabs_tobeadded; i++) {
// Add the new E-RABs at the corresponding rrc ue context of the gNB
ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
ue_context_p->ue_context.nb_of_e_rabs++;
// Add the new E-RABs at the corresponding rrc ue context of the gNB
UE->e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id;
UE->e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid;
memcpy(&UE->e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t));
UE->nb_of_e_rabs++;
//Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW
create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid;
memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
create_tunnel_req.eps_bearer_id[i] = UE->e_rab[i].param.e_rab_id;
create_tunnel_req.sgw_S1u_teid[i] = UE->e_rab[i].param.gtp_teid;
memcpy(&create_tunnel_req.sgw_addr[i], &UE->e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t));
inde_list[i] = i;
LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n",
i,
......@@ -287,10 +270,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
create_tunnel_req.sgw_S1u_teid[i]);
}
create_tunnel_req.rnti = ue_context_p->ue_id_rnti;
create_tunnel_req.rnti = ue_context_p->ue_context.rnti;
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_id_rnti, 0, 0,rrc->module_id);
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");
......@@ -306,8 +289,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
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;
for(int i=0; i<ue_context_p->ue_context.nb_of_e_rabs; i++) {
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
for (int i = 0; i < UE->nb_of_e_rabs; i++) {
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = UE->e_rab[i].param.e_rab_id;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i];
memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t));
//The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes
......@@ -333,7 +316,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n");
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity;
//X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size
// Send to X2 entity to transport to MeNB
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config,
......@@ -357,8 +340,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
&rrc->carrier.mib,
NULL,
1, // add_ue flag
ue_context_p->ue_id_rnti,
ue_context_p->ue_context.secondaryCellGroup);
ue_context_p->ue_context.rnti,
UE->secondaryCellGroup);
} else {
rrc_mac_config_req_gNB(rrc->module_id,
rrc->configuration.pdsch_AntennaPorts,
......@@ -369,11 +352,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
NULL,
NULL,
1, // add_ue flag
ue_context_p->ue_id_rnti,
ue_context_p->ue_context.secondaryCellGroup);
ue_context_p->ue_context.rnti,
UE->secondaryCellGroup);
}
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0, rrc->module_id);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, rrc->module_id);
if (get_softmodem_params()->do_ra) ctxt.enb_flag = 0;
LOG_W(RRC,
"Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %lx, frame %d, subframe %d eNB_index %d \n",
......@@ -384,20 +367,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
ctxt.subframe,
ctxt.eNB_index);
nr_pdcp_add_drbs(ctxt.enb_flag,
ctxt.rntiMaybeUEid,
0,
ue_context_p->ue_context.rb_config->drb_ToAddModList,
(ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
kUPenc,
kUPint,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
nr_rrc_rlc_config_asn1_req(&ctxt,
get_softmodem_params()->sa ? ue_context_p->ue_context.rb_config->srb_ToAddModList : NULL,
ue_context_p->ue_context.rb_config->drb_ToAddModList,
ue_context_p->ue_context.rb_config->drb_ToReleaseList,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
nr_pdcp_add_drbs(
ctxt.enb_flag, ctxt.rntiMaybeUEid, 0, UE->rb_config->drb_ToAddModList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, kUPint, UE->secondaryCellGroup->rlc_BearerToAddModList);
nr_rrc_rlc_config_asn1_req(
&ctxt, get_softmodem_params()->sa ? UE->rb_config->srb_ToAddModList : NULL, UE->rb_config->drb_ToAddModList, UE->rb_config->drb_ToReleaseList, UE->secondaryCellGroup->rlc_BearerToAddModList);
LOG_D(RRC, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %lx\n", __FUNCTION__, __LINE__, ctxt.rntiMaybeUEid);
}
......
......@@ -22,6 +22,20 @@
#include "rrc_gNB_radio_bearers.h"
#include "oai_asn1.h"
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
{
int j;
for (j = 0; j < ue->nb_of_pdusessions; j++)
if (id == ue->pduSession[j].param.pdusession_id)
break;
if (j == ue->nb_of_pdusessions && create)
ue->nb_of_pdusessions++;
else
return NULL;
AssertFatal(ue->nb_of_pdusessions < NGAP_MAX_PDU_SESSION, "");
return ue->pduSession + j;
}
NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering)
{
NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config));
......@@ -49,8 +63,6 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *ue, uint8_t drb_id, rrc_pdu_session
{
asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
*qfi = pduSession->param.qos[qos_flow_index].qfi;
asn1cSeqAdd(&SDAP_config->mappedQoS_FlowsToAdd->list, qfi);
if(pduSession->param.qos[qos_flow_index].fiveQI > 5)
pduSession->param.used_drbs[drb_id - 1] = DRB_ACTIVE_NONGBR;
else
......
......@@ -39,4 +39,6 @@ NR_DRB_ToAddMod_t *generateDRB(gNB_RRC_UE_t *rrc_ue, uint8_t drb_id, rrc_pdu_ses
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create);
#endif
......@@ -435,14 +435,9 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, bool has_sdap_rx, bool has_sdap
if(is_defaultDRB) {
sdap_entity->default_drb = drb_identity;
LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb);
if(mappedQFIs2AddCount) {
LOG_D(SDAP, "RRC updating mapping rules\n");
for (int i = 0; i < mappedQFIs2AddCount; i++)
{
sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx);
}
}
LOG_D(SDAP, "RRC updating mapping rules: %d\n", mappedQFIs2AddCount);
for (int i = 0; i < mappedQFIs2AddCount; i++)
sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx);
}
sdap_entity->next_entity = sdap_info.sdap_entity_llist;
......
......@@ -859,6 +859,7 @@ void *nas_nrue_task(void *args_p)
instance = msg_p->ittiMsgHeader.originInstance;
Mod_id = instance ;
uicc_t *uicc=checkUicc(Mod_id);
LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME(msg_p));
if (instance == INSTANCE_DEFAULT) {
printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n",
......@@ -867,84 +868,83 @@ void *nas_nrue_task(void *args_p)
}
switch (ITTI_MSG_ID(msg_p)) {
case INITIALIZE_MESSAGE:
LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME (msg_p));
break;
case TERMINATE_MESSAGE:
itti_exit_task ();
break;
case MESSAGE_TEST:
LOG_I(NAS, "[UE %d] Received %s\n", Mod_id, ITTI_MSG_NAME (msg_p));
break;
case NAS_CELL_SELECTION_CNF:
LOG_I(NAS, "[UE %d] Received %s: errCode %u, cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
NAS_CELL_SELECTION_CNF (msg_p).errCode, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).tac);
// as_stmsi_t s_tmsi={0, 0};
// as_nas_info_t nas_info;
// plmn_t plmnID={0, 0, 0, 0};
// generateRegistrationRequest(&nas_info);
// nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0);
break;
case NAS_CELL_SELECTION_IND:
LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
NAS_CELL_SELECTION_IND (msg_p).cellID, NAS_CELL_SELECTION_IND (msg_p).tac);
/* TODO not processed by NAS currently */
break;
case NAS_PAGING_IND:
LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
NAS_PAGING_IND (msg_p).cause);
/* TODO not processed by NAS currently */
break;
case NAS_CONN_ESTABLI_CNF:
{
LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME (msg_p),
NAS_CONN_ESTABLI_CNF (msg_p).errCode, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
pdu_buffer = NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data;
msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
if(msg_type == REGISTRATION_ACCEPT){
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(Mod_id,&initialNasMsg, NULL);
if(initialNasMsg.length > 0){
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
case INITIALIZE_MESSAGE:
break;
case TERMINATE_MESSAGE:
itti_exit_task();
break;
case MESSAGE_TEST:
break;
case NAS_CELL_SELECTION_CNF:
LOG_I(NAS,
"[UE %d] Received %s: errCode %u, cellID %u, tac %u\n",
Mod_id,
ITTI_MSG_NAME(msg_p),
NAS_CELL_SELECTION_CNF(msg_p).errCode,
NAS_CELL_SELECTION_CNF(msg_p).cellID,
NAS_CELL_SELECTION_CNF(msg_p).tac);
// as_stmsi_t s_tmsi={0, 0};
// as_nas_info_t nas_info;
// plmn_t plmnID={0, 0, 0, 0};
// generateRegistrationRequest(&nas_info);
// nr_nas_itti_nas_establish_req(0, AS_TYPE_ORIGINATING_SIGNAL, s_tmsi, plmnID, nas_info.data, nas_info.length, 0);
break;
case NAS_CELL_SELECTION_IND:
LOG_I(NAS, "[UE %d] Received %s: cellID %u, tac %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_CELL_SELECTION_IND(msg_p).cellID, NAS_CELL_SELECTION_IND(msg_p).tac);
/* TODO not processed by NAS currently */
break;
case NAS_PAGING_IND:
LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_PAGING_IND(msg_p).cause);
/* TODO not processed by NAS currently */
break;
case NAS_CONN_ESTABLI_CNF: {
LOG_I(NAS, "[UE %d] Received %s: errCode %u, length %u\n", Mod_id, ITTI_MSG_NAME(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).errCode, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
pdu_buffer = NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data;
msg_type = get_msg_type(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
if (msg_type == REGISTRATION_ACCEPT) {
LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n");
as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(Mod_id, &initialNasMsg, NULL);
if (initialNasMsg.length > 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n");
}
as_nas_info_t pduEstablishMsg;
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg);
if (pduEstablishMsg.length > 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
} else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length);
}
as_nas_info_t pduEstablishMsg;
memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t));
generatePduSessionEstablishRequest(Mod_id, uicc, &pduEstablishMsg);
if(pduEstablishMsg.length > 0){
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_UPLINK_DATA_REQ);
NAS_UPLINK_DATA_REQ(message_p).UEid = Mod_id;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data;
NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length;
itti_send_msg_to_task(TASK_RRC_NRUE, instance, message_p);
LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n");
}
} else if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){
capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length);
}
break;
break;
}
case NAS_CONN_RELEASE_IND:
......
......@@ -284,70 +284,70 @@ void *ngap_gNB_process_itti_msg(void *notUsed) {
itti_exit_task();
break;
case NGAP_REGISTER_GNB_REQ: {
case NGAP_REGISTER_GNB_REQ:
/* Register a new gNB.
* in Virtual mode gNBs will be distinguished using the mod_id/
* Each gNB has to send an NGAP_REGISTER_GNB message with its
* own parameters.
*/
ngap_gNB_handle_register_gNB(instance, &NGAP_REGISTER_GNB_REQ(received_msg));
} break;
break;
case SCTP_NEW_ASSOCIATION_RESP: {
case SCTP_NEW_ASSOCIATION_RESP:
ngap_gNB_handle_sctp_association_resp(instance, &received_msg->ittiMsg.sctp_new_association_resp);
} break;
break;
case SCTP_DATA_IND: {
case SCTP_DATA_IND:
ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
} break;
break;
case NGAP_NAS_FIRST_REQ: {
case NGAP_NAS_FIRST_REQ:
ngap_gNB_handle_nas_first_req(instance, &NGAP_NAS_FIRST_REQ(received_msg));
} break;
break;
case NGAP_UPLINK_NAS: {
case NGAP_UPLINK_NAS:
ngap_gNB_nas_uplink(instance, &NGAP_UPLINK_NAS(received_msg));
} break;
break;
case NGAP_UE_CAPABILITIES_IND: {
case NGAP_UE_CAPABILITIES_IND:
ngap_gNB_ue_capabilities(instance, &NGAP_UE_CAPABILITIES_IND(received_msg));
} break;
break;
case NGAP_INITIAL_CONTEXT_SETUP_RESP: {
case NGAP_INITIAL_CONTEXT_SETUP_RESP:
ngap_gNB_initial_ctxt_resp(instance, &NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg));
} break;
break;
case NGAP_PDUSESSION_SETUP_RESP: {
case NGAP_PDUSESSION_SETUP_RESP:
ngap_gNB_pdusession_setup_resp(instance, &NGAP_PDUSESSION_SETUP_RESP(received_msg));
} break;
break;
case NGAP_PDUSESSION_MODIFY_RESP: {
case NGAP_PDUSESSION_MODIFY_RESP:
ngap_gNB_pdusession_modify_resp(instance, &NGAP_PDUSESSION_MODIFY_RESP(received_msg));
} break;
break;
case NGAP_NAS_NON_DELIVERY_IND: {
case NGAP_NAS_NON_DELIVERY_IND:
ngap_gNB_nas_non_delivery_ind(instance, &NGAP_NAS_NON_DELIVERY_IND(received_msg));
} break;
break;
case NGAP_PATH_SWITCH_REQ: {
case NGAP_PATH_SWITCH_REQ:
ngap_gNB_path_switch_req(instance, &NGAP_PATH_SWITCH_REQ(received_msg));
} break;
break;
case NGAP_PDUSESSION_MODIFICATION_IND: {
case NGAP_PDUSESSION_MODIFICATION_IND:
ngap_gNB_generate_PDUSESSION_Modification_Indication(instance, &NGAP_PDUSESSION_MODIFICATION_IND(received_msg));
} break;
break;
case NGAP_UE_CONTEXT_RELEASE_COMPLETE: {
case NGAP_UE_CONTEXT_RELEASE_COMPLETE:
ngap_ue_context_release_complete(instance, &NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg));
} break;
break;
case NGAP_UE_CONTEXT_RELEASE_REQ: {
case NGAP_UE_CONTEXT_RELEASE_REQ:
ngap_ue_context_release_req(instance, &NGAP_UE_CONTEXT_RELEASE_REQ(received_msg));
} break;
break;
case NGAP_PDUSESSION_RELEASE_RESPONSE: {
case NGAP_PDUSESSION_RELEASE_RESPONSE:
ngap_gNB_pdusession_release_resp(instance, &NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg));
} break;
break;
default:
NGAP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
......
......@@ -70,8 +70,7 @@ int ngap_ue_context_release_complete(instance_t instance,
if ((ue_context_p = ngap_get_ue_context(ue_release_complete_p->gNB_ue_ngap_id)) == NULL) {
/* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */
NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n",
ue_release_complete_p->gNB_ue_ngap_id);
NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_release_complete_p->gNB_ue_ngap_id);
return -1;
}
......
......@@ -60,6 +60,7 @@ static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, uint8_t **buf
}
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n");
*buffer = res.buffer;
*len = res.result.encoded;
return 0;
......@@ -78,11 +79,12 @@ static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, uint
if (pdu->choice.successfulOutcome->procedureCode == tmp[i])
break;
if (i == sizeofArray(tmp)) {
NGAP_WARN("Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome->procedureCode);
NGAP_WARN("Unknown procedure ID (%ld) for successfull outcome message\n", pdu->choice.successfulOutcome->procedureCode);
return -1;
}
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n");
*buffer = res.buffer;
*len = res.result.encoded;
return 0;
......@@ -98,6 +100,7 @@ static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, ui
}
asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu);
AssertFatal(res.result.encoded > 0, "failed to encode NGAP msg\n");
*buffer = res.buffer;
*len = res.result.encoded;
return 0;
......@@ -129,7 +132,6 @@ int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len)
NGAP_DEBUG("Unknown message outcome (%d) or not implemented", (int)pdu->present);
return -1;
}
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu);
return ret;
}
......@@ -785,13 +785,8 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
//DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0);
//DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs);
if (ie == NULL) {
NGAP_WARN("AllowedNSSAI not present, forging 2 NSSAI\n");
AssertFatal(ie, "AllowedNSSAI not present, forging 2 NSSAI\n");
msg->nb_allowed_nssais = 2;
msg->allowed_nssai[0] = (ngap_allowed_NSSAI_t){.sST = 01, .sD_flag = 1, .sD = {1, 2, 3}};
msg->allowed_nssai[1] = (ngap_allowed_NSSAI_t){.sST = 01, .sD_flag = 1, .sD = {0, 0, 1}};
} else {
NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
msg->nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count;
......@@ -802,12 +797,9 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
if(allow_nssai_item_p->s_NSSAI.sD != NULL) {
msg->allowed_nssai[i].sD_flag = 1;
msg->allowed_nssai[i].sD[0] = allow_nssai_item_p->s_NSSAI.sD->buf[0];
msg->allowed_nssai[i].sD[1] = allow_nssai_item_p->s_NSSAI.sD->buf[1];
msg->allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2];
memcpy(msg->allowed_nssai[i].sD, allow_nssai_item_p->s_NSSAI.sD, sizeof(msg->allowed_nssai[i].sD));
}
}
}
/* id-UESecurityCapabilities */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
......@@ -981,25 +973,24 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id,
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq, true);
msg->nb_pdusessions_tosetup =
ie->value.choice.PDUSessionResourceSetupListSUReq.list.count;
msg->nb_pdusessions_tosetup = ie->value.choice.PDUSessionResourceSetupListSUReq.list.count;
for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) {
NGAP_PDUSessionResourceSetupItemSUReq_t *item_p = ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i];
msg->pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID;
for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) {
NGAP_PDUSessionResourceSetupItemSUReq_t *item_p = ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i];
msg->pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID;
// S-NSSAI
OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST);
if(item_p->s_NSSAI.sD != NULL) {
msg->allowed_nssai[i].sD_flag = 1;
msg->allowed_nssai[i].sD[0] = item_p->s_NSSAI.sD->buf[0];
msg->allowed_nssai[i].sD[1] = item_p->s_NSSAI.sD->buf[1];
msg->allowed_nssai[i].sD[2] = item_p->s_NSSAI.sD->buf[2];
}
allocCopy(&msg->pdusession_setup_params[i].nas_pdu, *item_p->pDUSessionNAS_PDU);
allocCopy(&msg->pdusession_setup_params[i].pdusessionTransfer, item_p->pDUSessionResourceSetupRequestTransfer);
// S-NSSAI
OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST);
if (item_p->s_NSSAI.sD != NULL) {
msg->allowed_nssai[i].sD_flag = 1;
msg->allowed_nssai[i].sD[0] = item_p->s_NSSAI.sD->buf[0];
msg->allowed_nssai[i].sD[1] = item_p->s_NSSAI.sD->buf[1];
msg->allowed_nssai[i].sD[2] = item_p->s_NSSAI.sD->buf[2];
}
allocCopy(&msg->pdusession_setup_params[i].nas_pdu, *item_p->pDUSessionNAS_PDU);
allocCopy(&msg->pdusession_setup_params[i].pdusessionTransfer, item_p->pDUSessionResourceSetupRequestTransfer);
}
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
return 0;
......
......@@ -169,7 +169,7 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf
/* The gNB should allocate a unique gNB UE NGAP ID for this UE. The value
* will be used for the duration of the connectivity.
*/
struct ngap_gNB_ue_context_s *ue_desc_p = calloc(1, sizeof(ue_desc_p));
struct ngap_gNB_ue_context_s *ue_desc_p = calloc(1, sizeof(*ue_desc_p));
DevAssert(ue_desc_p != NULL);
/* Keep a reference to the selected AMF */
ue_desc_p->amf_ref = amf_desc_p;
......@@ -639,12 +639,6 @@ int ngap_gNB_initial_ctxt_resp(instance_t instance, ngap_initial_context_setup_r
asn1cSequenceAdd(pdusessionTransfer.dLQosFlowPerTNLInformation.associatedQosFlowList.list, NGAP_AssociatedQosFlowItem_t, ass_qos_item_p);
/* qosFlowIdentifier */
ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi;
/* qosFlowMappingIndication */
// if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) {
// ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication));
// *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind;
// }
}
void *pdusessionTransfer_buffer;
......@@ -741,7 +735,6 @@ int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap
{
ngap_gNB_instance_t *ngap_gNB_instance_p;
struct ngap_gNB_ue_context_s *ue_context_p;
NGAP_NGAP_PDU_t pdu;
uint8_t *buffer;
uint32_t length;
/* Retrieve the NGAP gNB instance associated with Mod_id */
......@@ -768,7 +761,7 @@ int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap
}
/* Prepare the NGAP message to encode */
memset(&pdu, 0, sizeof(pdu));
NGAP_NGAP_PDU_t pdu = {0};
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu.choice.initiatingMessage, head);
head->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication;
......@@ -781,7 +774,7 @@ int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_AMF_UE_NGAP_ID;
// ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id;
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id);
}
/* mandatory */
{
......@@ -789,7 +782,7 @@ int ngap_gNB_ue_capabilities(instance_t instance, ngap_ue_cap_info_ind_t *ue_cap
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
ie->criticality = NGAP_Criticality_reject;
ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_RAN_UE_NGAP_ID;
ie->value.choice.RAN_UE_NGAP_ID = ue_cap_info_ind_p->gNB_ue_ngap_id;
ie->value.choice.RAN_UE_NGAP_ID = (int64_t)ue_cap_info_ind_p->gNB_ue_ngap_id;
}
/* mandatory */
{
......
......@@ -43,7 +43,7 @@
/* Tree of UE ordered by gNB_ue_ngap_id's
* NO INSTANCE, the 32 bits id is large enough to handle all UEs, regardless the cell, gNB, ...
*/
static RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head = RB_INITIALIZER(root);
static RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head = RB_INITIALIZER(&ngap_ue_head);
/* Generate the tree management functions prototypes */
RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries, ngap_gNB_compare_gNB_ue_ngap_id);
......@@ -67,7 +67,7 @@ RB_GENERATE(ngap_ue_map, ngap_gNB_ue_context_s, entries,
void ngap_store_ue_context(struct ngap_gNB_ue_context_s *ue_desc_p)
{
if (!RB_INSERT(ngap_ue_map, &ngap_ue_head, ue_desc_p))
if (RB_INSERT(ngap_ue_map, &ngap_ue_head, ue_desc_p))
LOG_E(NGAP, "Bug in UE uniq number allocation %u, we try to add a existing UE\n", ue_desc_p->gNB_ue_ngap_id);
return;
}
......
......@@ -58,8 +58,7 @@ typedef struct ngap_gNB_ue_context_s {
*/
uint32_t gNB_ue_ngap_id;
/* Uniquely identifies the UE within AMF. Encoded on 32 bits. */
uint64_t amf_ue_ngap_id:40;
uint64_t amf_ue_ngap_id;
/* Stream used for this particular UE */
int32_t tx_stream;
......
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