diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 832f785551..6fcf5b7ea3 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -84,7 +84,7 @@ int nr_rlc_get_available_tx_space(const rnti_t rntiP, const logical_chan_id_t ch return 0; } -void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, NR_CellGroupConfig_t *cell_groupConfig_from_DU) +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) { abort(); } diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 7b991e5918..7c67b22756 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -46,8 +46,8 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp) -MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req) -MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_req_t, f1ap_ue_context_modification_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_resp_t, f1ap_ue_context_modification_resp) /* CU -> DU*/ MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 9bdf7f0330..08cc03c4fa 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -341,7 +341,6 @@ typedef struct f1ap_drb_to_be_setup_s { typedef struct f1ap_srb_to_be_setup_s { long srb_id; - rlc_mode_t rlc_mode; uint8_t lcid; } f1ap_srb_to_be_setup_t; @@ -409,7 +408,7 @@ typedef struct f1ap_ue_context_setup_s { ReconfigurationCompl_t ReconfigComplOutcome; uint8_t *rrc_container; int rrc_container_length; -} f1ap_ue_context_setup_t; +} f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t; typedef enum F1ap_Cause_e { F1AP_CAUSE_NOTHING, /* No components present */ diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 901932f54b..7cc23e88fa 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -171,7 +171,7 @@ void *F1AP_CU_task(void *arg) { case F1AP_UE_CONTEXT_MODIFICATION_REQ: CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), - &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); + &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 383f02f20a..3e2197c282 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -981,7 +981,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, return 0; } -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) { +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; uint8_t *buffer=NULL; @@ -1600,7 +1601,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_UEContextModificationResponseIEs_t *ie; DevAssert(pdu); msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); - f1ap_ue_context_setup_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); + f1ap_ue_context_modif_resp_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; int i; @@ -1609,7 +1610,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; - LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id); + LOG_D(F1AP, "f1ap_ue_context_modif_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id); /* GNB_DU_UE_F1AP_ID */ F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 87563e97b1..32a54bc6cc 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -72,8 +72,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, /* * UE Context Modification (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - f1ap_ue_context_setup_t *f1ap_ue_context_modification_req); +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index dfec14e1e3..9aa3c42213 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -37,29 +37,24 @@ #include "f1ap_du_ue_context_management.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" -#include "rrc_extern.h" -#include "openair2/RRC/NR/rrc_gNB_UE_context.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include -bool lteDURecvCb(protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool DURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) +{ // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); - // weird rb id management in 4G, not fully understand (looks bad design) - // overcomplex: if i understand, on the interface DRB start at 4 because there can be SRB 0..3 - // but it would be much simpler to use absolute numbering - // instead of this "srb flag" associated to these +/-4 - du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP-4,muiP, confirmP, sdu_buffer_sizeP, sdu); + du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu); return true; } @@ -138,7 +133,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = (uint8_t *)calloc(1,ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); memcpy(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->buf, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size; - LOG_I(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + LOG_D(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); } } @@ -810,17 +805,12 @@ static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, c return gtpv1Init(tmp); } -int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, - F1AP_F1AP_PDU_t *pdu) { - - MessageDef *msg_p; // message to RRC +int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) +{ F1AP_UEContextModificationRequest_t *container; int i; - DevAssert(pdu); - msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_setup_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + f1ap_ue_context_modif_req_t ue_context_modification = {0}; + f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req = &ue_context_modification; container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest; /* mandatory */ @@ -841,7 +831,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, if(f1ap_ue_context_modification_req->rnti<0) LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n"); else - LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); + LOG_D(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); /* SRB */ F1AP_UEContextModificationRequestIEs_t *ieSrb; @@ -967,15 +957,16 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n"); } } else { - LOG_W(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); + LOG_D(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); } - itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + ue_context_modification_request(f1ap_ue_context_modification_req); return 0; } //void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp) +{ F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationResponse_t *out; uint8_t *buffer=NULL; @@ -1062,6 +1053,21 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_contex drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id; for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; + transport_layer_addr_t tl_addr = {0}; + memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); + tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; + drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(false, instance)->gtpInst, + resp->rnti, + drb->drb_id, + drb->drb_id, + drb->up_ul_tnl[j].teid, + -1, // no qfi + tl_addr, + drb->up_ul_tnl[0].port, + DURecvCb, + NULL); + /* ADD */ asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index c834b3d84d..51b8fa6dce 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -72,7 +72,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_modif_resp_t *resp); int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e9a985b670..9794a55e7e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -44,10 +44,6 @@ #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" -/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ -#include "RRC/NR/nr_rrc_extern.h" -#include "RRC/NR/rrc_gNB_UE_context.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" @@ -2944,12 +2940,6 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) UE->CellGroup = cellGroupConfig; nr_mac_update_cellgroup(mac, UE->rnti, cellGroupConfig); - /* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ - if (NODE_IS_DU(rrc->node_type)) { - rrc_gNB_ue_context_t *ue = rrc_gNB_create_ue_context(UE->rnti, rrc, UE->rnti); - ue->ue_context.masterCellGroup = cellGroupConfig; - } - /* activate SRB0 */ nr_rlc_activate_srb0(UE->rnti, mac, UE, send_initial_ul_rrc_message); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 6e444b9816..006db8ac44 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -33,25 +33,27 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_set return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket); } -static void handle_ue_context_srbs_setup(const f1ap_ue_context_setup_t *req, - f1ap_ue_context_setup_t *resp, - NR_CellGroupConfig_t *cellGroupConfig) +static int handle_ue_context_srbs_setup(int rnti, + int srbs_len, + const f1ap_srb_to_be_setup_t *req_srbs, + f1ap_srb_to_be_setup_t **resp_srbs, + NR_CellGroupConfig_t *cellGroupConfig) { - DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL); + DevAssert(req_srbs != NULL && resp_srbs != NULL && cellGroupConfig != NULL); - resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; - resp->srbs_to_be_setup = calloc(req->srbs_to_be_setup_length, sizeof(*resp->srbs_to_be_setup)); - AssertFatal(resp->srbs_to_be_setup != NULL, "out of memory\n"); - for (int i = 0; i < req->srbs_to_be_setup_length; i++) { - f1ap_srb_to_be_setup_t *srb = &req->srbs_to_be_setup[i]; + *resp_srbs = calloc(srbs_len, sizeof(**resp_srbs)); + AssertFatal(*resp_srbs != NULL, "out of memory\n"); + for (int i = 0; i < srbs_len; i++) { + const f1ap_srb_to_be_setup_t *srb = &req_srbs[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb); - nr_rlc_add_srb(req->rnti, srb->srb_id, rlc_BearerConfig); + nr_rlc_add_srb(rnti, srb->srb_id, rlc_BearerConfig); - resp->srbs_to_be_setup[i] = *srb; + (*resp_srbs)[i] = *srb; int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); } + return srbs_len; } static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb) @@ -61,27 +63,31 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_set return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority); } -static void handle_ue_context_drbs_setup(const f1ap_ue_context_setup_t *req, - f1ap_ue_context_setup_t *resp, - NR_CellGroupConfig_t *cellGroupConfig) +static int handle_ue_context_drbs_setup(int rnti, + int drbs_len, + const f1ap_drb_to_be_setup_t *req_drbs, + f1ap_drb_to_be_setup_t **resp_drbs, + NR_CellGroupConfig_t *cellGroupConfig) { - DevAssert(req != NULL && resp != NULL && cellGroupConfig != NULL); + DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL); /* Note: the actual GTP tunnels are created in the F1AP breanch of * ue_context_*_response() */ - resp->drbs_to_be_setup_length = req->drbs_to_be_setup_length; - resp->drbs_to_be_setup = calloc(req->drbs_to_be_setup_length, sizeof(*resp->drbs_to_be_setup)); - AssertFatal(resp->drbs_to_be_setup != NULL, "out of memory\n"); - for (int i = 0; i < req->drbs_to_be_setup_length; i++) { - f1ap_drb_to_be_setup_t *drb = &req->drbs_to_be_setup[i]; + *resp_drbs = calloc(drbs_len, sizeof(**resp_drbs)); + AssertFatal(*resp_drbs != NULL, "out of memory\n"); + for (int i = 0; i < drbs_len; i++) { + const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); - nr_rlc_add_drb(req->rnti, drb->drb_id, rlc_BearerConfig); + nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig); - resp->drbs_to_be_setup[i] = *drb; + (*resp_drbs)[i] = *drb; + // just put same number of tunnels in DL as in UL + (*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length; int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); } + return drbs_len; } void ue_context_setup_request(const f1ap_ue_context_setup_t *req) @@ -105,11 +111,20 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); AssertFatal(UE != NULL, "did not find UE with RNTI %04x, but UE Context Setup Failed not implemented\n", req->rnti); - if (req->srbs_to_be_setup_length > 0) - handle_ue_context_srbs_setup(req, &resp, UE->CellGroup); + if (req->srbs_to_be_setup_length > 0) { + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + req->srbs_to_be_setup_length, + req->srbs_to_be_setup, + &resp.srbs_to_be_setup, + UE->CellGroup); + } if (req->drbs_to_be_setup_length > 0) { - handle_ue_context_drbs_setup(req, &resp, NULL); + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + req->drbs_to_be_setup_length, + req->drbs_to_be_setup, + &resp.drbs_to_be_setup, + UE->CellGroup); } if (req->rrc_container != NULL) @@ -147,6 +162,85 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) free(resp.du_to_cu_rrc_information); } +void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) +{ + gNB_MAC_INST *mac = RC.nrmac[0]; + f1ap_ue_context_modif_resp_t resp = { + .gNB_CU_ue_id = req->gNB_CU_ue_id, + .gNB_DU_ue_id = req->gNB_DU_ue_id, + .rnti = req->rnti, + }; + + if (req->cu_to_du_rrc_information != NULL) { + AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL, "CG-ConfigInfo not handled\n"); + AssertFatal(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList == NULL, "UE capabilities not handled yet\n"); + AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL, "MeasConfig not handled\n"); + } + + NR_SCHED_LOCK(&mac->sched_lock); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, req->rnti); + + if (req->srbs_to_be_setup_length > 0) { + resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(req->rnti, + req->srbs_to_be_setup_length, + req->srbs_to_be_setup, + &resp.srbs_to_be_setup, + UE->CellGroup); + } + + if (req->drbs_to_be_setup_length > 0) { + resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(req->rnti, + req->drbs_to_be_setup_length, + req->drbs_to_be_setup, + &resp.drbs_to_be_setup, + UE->CellGroup); + } + + if (req->rrc_container != NULL) + nr_rlc_srb_recv_sdu(req->rnti, DCCH, req->rrc_container, req->rrc_container_length); + + if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { + LOG_E(NR_MAC, + "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); + } + + if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0) { + /* TODO: if we change e.g. BWP or MCS table, need to automatically call + * configure_UE_BWP() (form nr_mac_update_timers()) after some time? */ + + resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); + AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n"); + resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024); + AssertFatal(resp.du_to_cu_rrc_information->cellGroupConfig != NULL, "out of memory\n"); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + UE->CellGroup, + resp.du_to_cu_rrc_information->cellGroupConfig, + 1024); + AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); + resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; + + /* works? */ + nr_mac_update_cellgroup(RC.nrmac[0], req->rnti, UE->CellGroup); + } + NR_SCHED_UNLOCK(&mac->sched_lock); + + /* some sanity checks, since we use the same type for request and response */ + DevAssert(resp.cu_to_du_rrc_information == NULL); + // resp.du_to_cu_rrc_information can be either NULL or not + DevAssert(resp.rrc_container == NULL && resp.rrc_container_length == 0); + + mac->mac_rrc.ue_context_modification_response(req, &resp); + + /* free the memory we allocated above */ + free(resp.srbs_to_be_setup); + free(resp.drbs_to_be_setup); + if (resp.du_to_cu_rrc_information != NULL) { + free(resp.du_to_cu_rrc_information->cellGroupConfig); + free(resp.du_to_cu_rrc_information); + } +} + void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) { /* mark UE as to be deleted after PUSCH failure */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 5ad3794a27..808277a7f4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" void ue_context_setup_request(const f1ap_ue_context_setup_t *req); +void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req); void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h index 0eb37a8148..5d7a7cd644 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -26,6 +26,8 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_response_func_t)(const f1ap_ue_context_setup_t* req, const f1ap_ue_context_setup_t *resp); +typedef void (*ue_context_modification_response_func_t)(const f1ap_ue_context_modif_req_t *req, + const f1ap_ue_context_modif_resp_t *resp); typedef void (*ue_context_release_request_func_t)(const f1ap_ue_context_release_req_t* req); typedef void (*ue_context_release_complete_func_t)(const f1ap_ue_context_release_complete_t *complete); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index e13991529c..6780fad873 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -55,6 +55,63 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } +static void ue_context_modification_response_direct(const f1ap_ue_context_modif_req_t *req, + const f1ap_ue_context_modif_resp_t *resp) +{ + (void)req; /* we don't need the request -- it is to set up GTP in F1 case */ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); + + f1ap_msg->gNB_CU_ue_id = resp->gNB_CU_ue_id; + f1ap_msg->gNB_DU_ue_id = resp->gNB_DU_ue_id; + f1ap_msg->rnti = resp->rnti; + f1ap_msg->mcc = resp->mcc; + f1ap_msg->mnc = resp->mnc; + f1ap_msg->mnc_digit_length = resp->mnc_digit_length; + f1ap_msg->nr_cellid = resp->nr_cellid; + f1ap_msg->servCellIndex = resp->servCellIndex; + AssertFatal(resp->cellULConfigured == NULL, "not handled\n"); + f1ap_msg->servCellId = resp->servCellId; + + DevAssert(resp->cu_to_du_rrc_information == NULL && resp->cu_to_du_rrc_information_length == 0); + if (resp->du_to_cu_rrc_information) { + f1ap_msg->du_to_cu_rrc_information = malloc(sizeof(*resp->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length; + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + } + + if (resp->drbs_to_be_setup_length > 0) { + DevAssert(resp->drbs_to_be_setup != NULL); + f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length; + f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i) + f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i]; + } + + DevAssert(resp->drbs_to_be_modified == NULL && resp->drbs_to_be_modified_length == 0); + f1ap_msg->QoS_information_type = resp->QoS_information_type; + AssertFatal(resp->drbs_failed_to_be_setup_length == 0 && resp->drbs_failed_to_be_setup == NULL, "not implemented yet\n"); + + if (resp->srbs_to_be_setup_length > 0) { + DevAssert(resp->srbs_to_be_setup != NULL); + f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) + f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; + } + + AssertFatal(resp->srbs_failed_to_be_setup_length == 0 && resp->srbs_failed_to_be_setup == NULL, "not implemented yet\n"); + + DevAssert(resp->rrc_container == NULL && resp->rrc_container_length == 0); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); +} + static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); @@ -94,6 +151,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_direct; + mac_rrc->ue_context_modification_response = ue_context_modification_response_direct; mac_rrc->ue_context_release_request = ue_context_release_request_direct; mac_rrc->ue_context_release_complete = ue_context_release_complete_direct; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 718a595e74..f122a13c34 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -60,6 +60,42 @@ static void ue_context_setup_response_f1ap(const f1ap_ue_context_setup_t *req, c itti_send_msg_to_task(TASK_DU_F1, 0, msg); } +static void ue_context_modification_response_f1ap(const f1ap_ue_context_modif_req_t *req, const f1ap_ue_context_modif_resp_t *resp) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_modif_resp_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg); + /* copy all fields, but reallocate rrc_containers! */ + *f1ap_msg = *resp; + + if (resp->srbs_to_be_setup_length > 0) { + DevAssert(resp->srbs_to_be_setup != NULL); + f1ap_msg->srbs_to_be_setup_length = resp->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup = calloc(f1ap_msg->srbs_to_be_setup_length, sizeof(*f1ap_msg->srbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->srbs_to_be_setup_length; ++i) + f1ap_msg->srbs_to_be_setup[i] = resp->srbs_to_be_setup[i]; + } + if (resp->drbs_to_be_setup_length > 0) { + DevAssert(resp->drbs_to_be_setup != NULL); + f1ap_msg->drbs_to_be_setup_length = resp->drbs_to_be_setup_length; + f1ap_msg->drbs_to_be_setup = calloc(f1ap_msg->drbs_to_be_setup_length, sizeof(*f1ap_msg->drbs_to_be_setup)); + for (int i = 0; i < f1ap_msg->drbs_to_be_setup_length; ++i) + f1ap_msg->drbs_to_be_setup[i] = resp->drbs_to_be_setup[i]; + } + + if (resp->du_to_cu_rrc_information != NULL) { + f1ap_msg->du_to_cu_rrc_information = calloc(1, sizeof(*resp->du_to_cu_rrc_information)); + AssertFatal(f1ap_msg->du_to_cu_rrc_information != NULL, "out of memory\n"); + f1ap_msg->du_to_cu_rrc_information_length = resp->du_to_cu_rrc_information_length; + du_to_cu_rrc_information_t *du2cu = f1ap_msg->du_to_cu_rrc_information; + du2cu->cellGroupConfig_length = resp->du_to_cu_rrc_information->cellGroupConfig_length; + du2cu->cellGroupConfig = calloc(du2cu->cellGroupConfig_length, sizeof(*du2cu->cellGroupConfig)); + AssertFatal(du2cu->cellGroupConfig != NULL, "out of memory\n"); + memcpy(du2cu->cellGroupConfig, resp->du_to_cu_rrc_information->cellGroupConfig, du2cu->cellGroupConfig_length); + } + + itti_send_msg_to_task(TASK_DU_F1, 0, msg); +} + static void ue_context_release_request_f1ap(const f1ap_ue_context_release_req_t* req) { MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); @@ -101,6 +137,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1 void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) { mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap; + mac_rrc->ue_context_modification_response = ue_context_modification_response_f1ap; mac_rrc->ue_context_release_request = ue_context_release_request_f1ap; mac_rrc->ue_context_release_complete = ue_context_release_complete_f1ap; mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index d9f3ed1188..b62c5f8562 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -662,6 +662,7 @@ typedef struct NR_bler_options { typedef struct nr_mac_rrc_ul_if_s { ue_context_setup_response_func_t ue_context_setup_response; + ue_context_modification_response_func_t ue_context_modification_response; ue_context_release_request_func_t ue_context_release_request; ue_context_release_complete_func_t ue_context_release_complete; initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index fe47aca73b..56ff6f01c2 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -190,6 +190,19 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); fill_DRB_configList(&ctxt, ue_context_p, xid); + e1ap_bearer_setup_resp_t resp = {0}; + resp.numPDUSessions = req->numPDUSessions; + for (int i = 0; i < resp.numPDUSessions; ++i) { + resp.pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup; + for (int j = 0; j < req->pduSession[i].numDRB2Setup; j++) { + DRB_nGRAN_to_setup_t *req_drb = req->pduSession[i].DRBnGRanList + j; + DRB_nGRAN_setup_t *resp_drb = resp.pduSession[i].DRBnGRanList + j; + resp_drb->id = req_drb->id; + resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup; + for (int k = 0; k < resp_drb->numQosFlowSetup; k++) + resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id; + } + } gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; // Fixme: xid not random, but almost! @@ -198,21 +211,26 @@ static void cucp_cuup_bearer_context_setup_direct(e1ap_bearer_setup_req_t *const int ret = drb_config_gtpu_create(&ctxt, ue_context_p, req, UE->DRB_configList, *SRB_configList2, rrc->e1_inst); if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n"); + // Used to store teids: if monolithic, will simply be NULL if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) { - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); + // intentionally empty } else { - e1ap_bearer_setup_resp_t resp; // Used to store teids int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; // GTP tunnel for DL fill_e1ap_bearer_setup_resp(&resp, req, gtpInst, UE->rnti, remote_port, my_addr); - - prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } + // actually, we should receive the corresponding context setup response + // message at the RRC and always react to this one. So in the following, we + // just call the corresponding message handler + prepare_and_send_ue_context_modification_f1(ue_context_p, &resp); } static void cucp_cuup_bearer_context_mod_direct(e1ap_bearer_setup_req_t *const req, instance_t instance, uint8_t xid) { + // only update GTP tunnels if it is really a CU + if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) + return; instance_t gtpInst = getCxt(CUtype, instance)->gtpInst; CU_update_UP_DL_tunnel(req, gtpInst, req->rnti); } diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index 46c7fc85f8..2728174603 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -26,6 +26,7 @@ #include "f1ap_messages_types.h" typedef void (*ue_context_setup_request_func_t)(const f1ap_ue_context_setup_t *req); +typedef void (*ue_context_modification_request_func_t)(const f1ap_ue_context_modif_req_t *req); typedef void (*ue_context_release_command_func_t)(const f1ap_ue_context_release_cmd_t *cmd); typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index b1ec661238..2d436c19e3 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -34,6 +34,7 @@ static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request; + mac_rrc->ue_context_modification_request = ue_context_modification_request; mac_rrc->ue_context_release_command = ue_context_release_command; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; } diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 0af1c79bd2..5bfeda2dc8 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -30,6 +30,38 @@ static void ue_context_setup_request_f1ap(const f1ap_ue_context_setup_t *req) f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); *f1ap_msg = *req; AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); + AssertFatal(req->drbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n"); + AssertFatal(req->srbs_to_be_setup == NULL, "drbs_to_be_setup not supported yet\n"); + if (req->rrc_container_length > 0) { + f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); + AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); + f1ap_msg->rrc_container_length = req->rrc_container_length; + memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length); + } + itti_send_msg_to_task(TASK_CU_F1, 0, msg); +} + +static void ue_context_modification_request_f1ap(const f1ap_ue_context_modif_req_t *req) +{ + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg); + *f1ap_msg = *req; + AssertFatal(req->cu_to_du_rrc_information == NULL, "cu_to_du_rrc_information not supported yet\n"); + AssertFatal(req->drbs_to_be_modified_length == 0, "drbs_to_be_modified not supported yet\n"); + if (req->drbs_to_be_setup_length > 0) { + int n = req->drbs_to_be_setup_length; + f1ap_msg->drbs_to_be_setup_length = n; + f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup)); + AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n"); + memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup)); + } + if (req->srbs_to_be_setup_length > 0) { + int n = req->srbs_to_be_setup_length; + f1ap_msg->srbs_to_be_setup_length = n; + f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup)); + AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n"); + memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup)); + } if (req->rrc_container_length > 0) { f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); @@ -66,6 +98,7 @@ static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rr void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) { mac_rrc->ue_context_setup_request = ue_context_setup_request_f1ap; + mac_rrc->ue_context_modification_request = ue_context_modification_request_f1ap; mac_rrc->ue_context_release_command = ue_context_release_command_f1ap; mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; } diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 8395175e0d..25e7563bbc 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -379,6 +379,7 @@ typedef struct { typedef struct nr_mac_rrc_dl_if_s { ue_context_setup_request_func_t ue_context_setup_request; + ue_context_modification_request_func_t ue_context_modification_request; ue_context_release_command_func_t ue_context_release_command; dl_rrc_message_transfer_func_t dl_rrc_message_transfer; } nr_mac_rrc_dl_if_t; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 384269748a..504aced681 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -142,11 +142,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( uint32_t nas_length, uint8_t *nas_buffer); -void -rrc_gNB_generate_dedicatedRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - NR_CellGroupConfig_t *cell_groupConfig_from_DU); +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP); void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ff862b1c23..dbb557fe85 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -112,23 +112,6 @@ mui_t rrc_gNB_mui = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -bool DURecvCb(protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { - // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue - mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); - memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); - du_rlc_data_req(ctxt_pP,srb_flagP, false, rb_idP,muiP, confirmP, sdu_buffer_sizeP, sdu); - return true; -} - static void nr_rrc_addmod_srbs(int rnti, const NR_SRB_ToAddModList_t *srb_list, const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list) @@ -642,17 +625,10 @@ void fill_DRB_configList(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_contex } //----------------------------------------------------------------------------- -void -rrc_gNB_generate_dedicatedRRCReconfiguration( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - NR_CellGroupConfig_t *cell_groupConfig_from_DU -) +void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP) //----------------------------------------------------------------------------- { gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - long drb_priority[NGAP_MAX_DRBS_PER_UE]; - NR_CellGroupConfig_t *cellGroupConfig = NULL; int xid = -1; int drb_id_to_setup_start = 1; @@ -683,7 +659,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( } xid = ue_p->pduSession[j].xid; - drb_priority[DRB_config->drb_Identity - 1] = 13; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) } /* If list is empty free the list and reset the address */ @@ -692,20 +667,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( dedicatedNAS_MessageList = NULL; } - if(cell_groupConfig_from_DU == NULL){ - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - // FIXME: fill_mastercellGroupConfig() won't fill the right priorities - fill_mastercellGroupConfig(cellGroupConfig, - ue_p->masterCellGroup, - rrc->um_on_default_drb, - (drb_id_to_setup_start < 2) ? 1 : 0, - DRB_configList, - drb_priority); - } - else{ - LOG_I(NR_RRC, "Master cell group originating from the DU \n"); - cellGroupConfig = cell_groupConfig_from_DU; - } + NR_CellGroupConfig_t *cellGroupConfig = ue_p->masterCellGroup; AssertFatal(xid > -1, "Invalid xid %d. No PDU sessions setup to configure.\n", xid); NR_SRB_ToAddModList_t *SRB_configList2 = NULL; @@ -2067,6 +2029,7 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ uint8_t xid = reconfig_complete->rrc_TransactionIdentifier; rrc_gNB_process_RRCReconfigurationComplete(ctxt_pP, ue_context_p, xid); + bool successful_reconfig = true; if (get_softmodem_params()->sa) { switch (UE->xids[xid]) { case RRC_PDUSESSION_RELEASE: { @@ -2085,10 +2048,29 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ case RRC_FIRST_RECONF: rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; + case RRC_DEFAULT_RECONF: + /* nothing to do */ + break; default: LOG_E(RRC, "Received unexpected xid: %d\n", xid); + successful_reconfig = false; + break; } } + + gNB_RRC_INST *rrc = RC.nrrrc[0]; + f1ap_ue_context_modif_req_t ue_context_modif_req = { + .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .rnti = UE->rnti, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .ReconfigComplOutcome = successful_reconfig ? RRCreconf_success : RRCreconf_failure, + }; + rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } //----------------------------------------------------------------------------- int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, @@ -2357,158 +2339,9 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC rrc_remove_nsa_user(rrc, m->rnti); } -static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, instance_t instance) -{ - f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(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]; - gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - 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); - uint32_t incoming_teid = 0; - NR_CellGroupConfig_t *cellGroupConfig = NULL; - - /* Configure SRB2 */ - NR_SRB_ToAddMod_t *SRB2_config = NULL; - NR_SRB_ToAddModList_t *SRB_configList = NULL; - uint8_t SRBs_before_new_addition = 0; - - if(req->srbs_to_be_setup_length>0){ - if (UE->SRB_configList == NULL) { - LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); - UE->SRB_configList = CALLOC(1, sizeof(*UE->SRB_configList)); - } - SRB_configList = UE->SRB_configList; - SRBs_before_new_addition = SRB_configList->list.count; - for (int i=0; isrbs_to_be_setup_length; i++){ - SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id; - asn1cSeqAdd(&SRB_configList->list, SRB2_config); - } - } - - /* Configure DRB */ - NR_DRB_ToAddMod_t *DRB_config = NULL; - NR_DRB_ToAddModList_t *DRB_configList = NULL; - int drb_id_to_setup_start = 0; - long drb_priority[NGAP_MAX_DRBS_PER_UE]; - if(req->drbs_to_be_setup_length>0){ - if (UE->DRB_configList == NULL) { - UE->DRB_configList = CALLOC(1, sizeof(*UE->DRB_configList)); - } - DRB_configList = UE->DRB_configList; - for (int i=0; idrbs_to_be_setup_length; i++){ - DRB_config = CALLOC(1, sizeof(*DRB_config)); - DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; - if (drb_id_to_setup_start == 0) drb_id_to_setup_start = DRB_config->drb_Identity; - asn1cSeqAdd(&DRB_configList->list, DRB_config); - f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; - transport_layer_addr_t addr; - memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); - addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; - extern instance_t DUuniqInstance; - if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; - incoming_teid = newGtpuCreateTunnel(DUuniqInstance, - req->rnti, - drb_p.drb_id, - drb_p.drb_id, - drb_p.up_ul_tnl[0].teid, - -1, // no qfi - addr, - drb_p.up_ul_tnl[0].port, - DURecvCb, - NULL); - /* TODO: hardcoded to 13 for the time being, to be changed? */ - drb_priority[DRB_config->drb_Identity-1] = 13; - } - } - - if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_mastercellGroupConfig(cellGroupConfig, - UE->masterCellGroup, - rrc->um_on_default_drb, - drb_id_to_setup_start < 2 ? 1 : 0, - DRB_configList, - drb_priority); - apply_macrlc_config(rrc, ue_context_p, &ctxt); - } - if(req->ReconfigComplOutcome == RRCreconf_failure){ - LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n"); - } - else if(req->ReconfigComplOutcome == RRCreconf_success){ - LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n"); - if (UE->DRB_configList != NULL) { - LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); - uint8_t drb_id = UE->DRB_configList->list.array[0]->drb_Identity; - rnti_t rnti = UE->rnti; - int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id + 3); - LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); - MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, - sizeof(gtpv1u_tunnel_data_req_t)); - gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg); - req->pdusession_id = drb_id; - req->ue_id = rnti; - req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead - extern instance_t DUuniqInstance; - itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg); - } - } - - /* Fill the UE context setup response ITTI message to send to F1AP */ - resp->gNB_CU_ue_id = req->gNB_CU_ue_id; - resp->rnti = ctxt.rntiMaybeUEid; - if(DRB_configList){ - if(DRB_configList->list.count > 0){ - resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); - resp->drbs_to_be_setup_length = DRB_configList->list.count; - for (int i=0; ilist.count; i++){ - resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity; - resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM; - resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid; - resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr); - resp->drbs_to_be_setup[i].up_dl_tnl_length = 1; - } - } - else{ - LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context modification request with a DRB to setup list\n"); - } - } - if(SRB_configList){ - if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){ - resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t)); - resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; - for (int i=SRBs_before_new_addition; ilist.count; i++){ - resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity; - } - } - else{ - LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); - } - } - else{ - LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); - } - - //if(cellGroupConfig != NULL) { - resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t)); - resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - UE->masterCellGroup, //(void *)cellGroupConfig, - resp->du_to_cu_rrc_information->cellGroupConfig, - 1024); - resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; - //} - itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); -} - static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance_t instance) { - f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + f1ap_ue_context_setup_t *resp = &F1AP_UE_CONTEXT_SETUP_RESP(msg_p); gNB_RRC_INST *rrc = RC.nrrrc[instance]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; @@ -2566,75 +2399,52 @@ static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, instance_t instance) { - f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + f1ap_ue_context_modif_resp_t *resp = &F1AP_UE_CONTEXT_MODIFICATION_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]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, resp->rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - e1ap_bearer_setup_req_t req = {0}; - req.numPDUSessionsMod = UE->nb_of_pdusessions; - req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; - req.rnti = UE->rnti; - for (int i=0; i < req.numPDUSessionsMod; i++) { - req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; - for (int j=0; j < resp->drbs_to_be_setup_length; j++) { - f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; - DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j; + if (resp->drbs_to_be_setup_length > 0) { + e1ap_bearer_setup_req_t req = {0}; + req.numPDUSessionsMod = UE->nb_of_pdusessions; + req.gNB_cu_cp_ue_id = UE->gNB_ue_ngap_id; + req.rnti = UE->rnti; + for (int i = 0; i < req.numPDUSessionsMod; i++) { + req.pduSessionMod[i].numDRB2Modify = resp->drbs_to_be_setup_length; + for (int j = 0; j < resp->drbs_to_be_setup_length; j++) { + f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j; + DRB_nGRAN_to_setup_t *drb_e1 = req.pduSessionMod[i].DRBnGRanModList + j; - drb_e1->id = drb_f1->drb_id; - drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length; - drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address; - drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid; - } - } - - // send the F1 response message up to update F1-U tunnel info - // it seems the rrc transaction id (xid) is not needed here - rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); - - NR_CellGroupConfig_t *cellGroupConfig = NULL; - - if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&cellGroupConfig, - (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, - (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); - - if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"Cell group config decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 ); - return; - } - //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); - - if (UE->masterCellGroup == NULL) { - UE->masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); - } - - if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ - if (UE->masterCellGroup->rlc_BearerToAddModList != NULL) { - int ue_ctxt_rlc_Bearers = UE->masterCellGroup->rlc_BearerToAddModList->list.count; - for(int i=ue_ctxt_rlc_Bearers; irlc_BearerToAddModList->list.count; i++){ - asn1cSeqAdd(&UE->masterCellGroup->rlc_BearerToAddModList->list, cellGroupConfig->rlc_BearerToAddModList->list.array[i - ue_ctxt_rlc_Bearers]); - } - } else { - LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); - UE->masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(UE->masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + drb_e1->id = drb_f1->drb_id; + drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length; + drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address; + drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid; } } - LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n"); - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); + + // send the F1 response message up to update F1-U tunnel info + // it seems the rrc transaction id (xid) is not needed here + rrc->cucp_cuup.bearer_context_mod(&req, instance, 0); + } + + if (resp->du_to_cu_rrc_information != NULL && resp->du_to_cu_rrc_information->cellGroupConfig != NULL) { + LOG_W(RRC, "UE context modification response contains new CellGroupConfig for UE %04x, triggering reconfiguration\n", UE->rnti); + NR_CellGroupConfig_t *cellGroupConfig = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroupConfig, + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed > 0, "Cell group config decode error\n"); + + if (UE->masterCellGroup) { + ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup); + LOG_I(RRC, "UE %04x replacing existing CellGroupConfig with new one received from DU\n", UE->rnti); } + UE->masterCellGroup = cellGroupConfig; - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); - - free(cellGroupConfig->rlc_BearerToAddModList); - free(cellGroupConfig); + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p); } } @@ -2817,46 +2627,48 @@ int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { return 0; } -void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, - e1ap_bearer_setup_resp_t *e1ap_resp) { +void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p, e1ap_bearer_setup_resp_t *e1ap_resp) +{ + /* Generate a UE context modification request message towards the DU to + * instruct the DU for SRB2 and DRB configuration and get the updates on + * master cell group config from the DU*/ - /*Generate a UE context modification request message towards the DU to instruct the DU - *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ + gNB_RRC_INST *rrc = RC.nrrrc[0]; gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - protocol_ctxt_t ctxt = {0}; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0); - // TODO: So many hard codings - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); - f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(message_p); - req->rnti = UE->rnti; - req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; - req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; - req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; - req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid; - - /*Instruction towards the DU for SRB2 configuration*/ - req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); - req->srbs_to_be_setup_length = 1; - f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; - SRBs[0].srb_id = 2; - SRBs[0].lcid = 2; - - /*Instruction towards the DU for DRB configuration and tunnel creation*/ - req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup; - req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length); - for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) { - f1ap_drb_to_be_setup_t *DRBs = req->drbs_to_be_setup + i; - DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; - DRBs[i].rlc_mode = RLC_MODE_AM; - DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; - DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd; - DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; - DRBs[i].up_ul_tnl_length = 1; + /* Instruction towards the DU for DRB configuration and tunnel creation */ + int nb_drb = e1ap_resp->pduSession[0].numDRBSetup; + f1ap_drb_to_be_setup_t drbs[nb_drb]; + for (int i = 0; i < nb_drb; i++) { + drbs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id; + drbs[i].rlc_mode = rrc->um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; + drbs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; + drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd; + drbs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; + drbs[i].up_ul_tnl_length = 1; } - itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); + /* Instruction towards the DU for SRB2 configuration */ + int nb_srb = 1; + f1ap_srb_to_be_setup_t srbs[nb_srb]; + srbs[0].srb_id = 2; + srbs[0].lcid = 2; + + f1ap_ue_context_modif_req_t ue_context_modif_req = { + .gNB_CU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .gNB_DU_ue_id = 0xffffffff, /* filled by F1 for the moment */ + .rnti = UE->rnti, + .mcc = rrc->configuration.mcc[0], + .mnc = rrc->configuration.mnc[0], + .mnc_digit_length = rrc->configuration.mnc_digit_length[0], + .nr_cellid = rrc->nr_cellid, + .servCellId = 0, /* TODO: correct value? */ + .srbs_to_be_setup_length = nb_srb, + .srbs_to_be_setup = srbs, + .drbs_to_be_setup_length = nb_drb, + .drbs_to_be_setup = drbs, + }; + rrc->mac_rrc.ue_context_modification_request(&ue_context_modif_req); } void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { @@ -3047,10 +2859,6 @@ void *rrc_gnb_task(void *args_p) { rrc_CU_process_ue_context_modification_response(msg_p, instance); break; - case F1AP_UE_CONTEXT_MODIFICATION_REQ: - rrc_DU_process_ue_context_modification_request(msg_p, instance); - break; - case F1AP_UE_CONTEXT_RELEASE_REQ: rrc_CU_process_ue_context_release_request(msg_p); break;