diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index cc29a92ebb..bed69ae455 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -38,8 +38,6 @@ #include "rrc_extern.h" #include "openair2/RRC/NR/rrc_gNB_NGAP.h" -#include -#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h" static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) { @@ -503,19 +501,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ - /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ - transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, - f1ap_ue_context_setup_req->gNB_CU_ue_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - 0xFFFF, // We will set the right value from DU answer - -1, // no qfi - addr, // We will set the right value from DU answer - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, - cu_f1u_data_req, - NULL); + DevAssert(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid > 0); /* 12.3.1 ULTunnels_ToBeSetup_Item */ asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); @@ -688,11 +674,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_ F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst, - f1ap_ue_context_setup_resp->gNB_DU_ue_id, - (ebi_t)drbs_setup_item_p->dRBID, - drb_p->up_dl_tnl[0].tl_address, - drb_p->up_dl_tnl[0].teid); } } @@ -1569,9 +1550,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; /* dRBID */ drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id; - newGtpuDeleteOneTunnel(getCxt(0)->gtpInst, - f1ap_ue_context_modification_req->gNB_CU_ue_id, - f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } } @@ -1644,11 +1622,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst, - f1ap_ue_context_modification_resp->gNB_CU_ue_id, - (ebi_t)drbs_setupmod_item_p->dRBID, - drb_p->up_dl_tnl[0].tl_address, - drb_p->up_dl_tnl[0].teid); } } // SRBs_FailedToBeSetupMod_List diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e306463b66..e175b215bb 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -40,24 +40,6 @@ #include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" -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 - uint8_t *sdu = malloc16(sdu_buffer_sizeP); - memcpy(sdu, 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; -} - int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { F1AP_UEContextSetupRequest_t *container; @@ -305,6 +287,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set ie7->criticality = F1AP_Criticality_ignore; ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; // asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); @@ -315,14 +298,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set /* ADD */ F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; /* dRBID */ - drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id; + drbs_setup_item->dRBID = drb->drb_id; /* OPTIONAL */ /* lCID */ //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); //drbs_setup_item.lCID = 1L; - for (int j=0; jdrbs_to_be_setup[i].up_dl_tnl_length; j++) { + for (int j = 0; j < drb->up_dl_tnl_length; j++) { + const f1ap_up_tnl_t *tnl = &drb->up_dl_tnl[j]; + DevAssert(tnl->teid > 0); + /* ADD */ asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); @@ -330,12 +316,9 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set /* gTPTunnel */ asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ - INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID); } // for j } // for i @@ -1008,7 +991,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t DevAssert(tbrel->id == F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item); DevAssert(tbrel->value.present == F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item); f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id = tbrel->value.choice.DRBs_ToBeReleased_Item.dRBID; - newGtpuDeleteOneTunnel(0, f1ap_ue_context_modification_req->gNB_DU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } } @@ -1166,20 +1148,8 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont 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(0)->gtpInst, - resp->gNB_DU_ue_id, - 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); + const f1ap_up_tnl_t *tnl = &resp->drbs_to_be_setup[i].up_dl_tnl[j]; + DevAssert(tnl->teid > 0); /* ADD */ asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, @@ -1188,12 +1158,9 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont /* gTPTunnel */ asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ - INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID); } // for j } // for i } 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 04f2c2fdc9..44c7839463 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -23,8 +23,11 @@ #include "mac_proto.h" #include "openair2/F1AP/f1ap_ids.h" +#include "openair2/F1AP/f1ap_common.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "F1AP_CauseRadioNetwork.h" +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -34,6 +37,59 @@ const uint64_t qos_fiveqi[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5, const uint64_t qos_priority[26] = {20, 40, 30, 50, 7, 20, 15, 56, 56, 56, 56, 56, 10, 60, 70, 80, 90, 5, 55, 65, 68, 19, 22, 24, 21, 18}; +static instance_t get_f1_gtp_instance(void) +{ + const f1ap_cudu_inst_t *inst = getCxt(0); + if (!inst) + return -1; // means no F1 + return inst->gtpInst; +} + +static int drb_gtpu_create(instance_t instance, + uint32_t ue_id, + int incoming_id, + int outgoing_id, + int qfi, + in_addr_t tlAddress, // only IPv4 now + teid_t outgoing_teid, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP, + gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp) +{ + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; + create_tunnel_req.incoming_rb_id[0] = incoming_id; + create_tunnel_req.pdusession_id[0] = outgoing_id; + memcpy(&create_tunnel_req.dst_addr[0].buffer, &tlAddress, sizeof(uint8_t) * 4); + create_tunnel_req.dst_addr[0].length = 32; + create_tunnel_req.outgoing_teid[0] = outgoing_teid; + create_tunnel_req.outgoing_qfi[0] = qfi; + create_tunnel_req.num_tunnels = 1; + create_tunnel_req.ue_id = ue_id; + + // we use gtpv1u_create_ngu_tunnel because it returns the interface + // address and port of the interface; apart from that, we also might call + // newGtpuCreateTunnel() directly + return gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, callBack, callBackSDAP); +} + +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 + uint8_t *sdu = malloc16(sdu_buffer_sizeP); + memcpy(sdu, 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 long get_lcid_from_drbid(int drb_id) { return drb_id + 3; /* LCID is DRB + 3 */ @@ -133,6 +189,7 @@ static int handle_ue_context_drbs_setup(int rnti, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL); + instance_t f1inst = get_f1_gtp_instance(); /* Note: the actual GTP tunnels are created in the F1AP breanch of * ue_context_*_response() */ @@ -140,12 +197,32 @@ static int handle_ue_context_drbs_setup(int rnti, 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]; + f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig); - (*resp_drbs)[i] = *drb; + *resp_drb = *drb; // just put same number of tunnels in DL as in UL - (*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length; + DevAssert(drb->up_ul_tnl_length == 1); + resp_drb->up_dl_tnl_length = drb->up_ul_tnl_length; + + if (f1inst >= 0) { // we actually use F1-U + int qfi = -1; // don't put PDU session marker in GTP + gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0}; + int ret = drb_gtpu_create(f1inst, + rnti, + drb->drb_id, + drb->drb_id, + qfi, + drb->up_ul_tnl[0].tl_address, + drb->up_ul_tnl[0].teid, + DURecvCb, + NULL, + &resp_f1); + AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n"); + memcpy(&resp_drb->up_dl_tnl[0].tl_address, &resp_f1.gnb_addr.buffer, 4); + resp_drb->up_dl_tnl[0].teid = resp_f1.gnb_NGu_teid[0]; + } int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); @@ -159,6 +236,7 @@ static int handle_ue_context_drbs_release(int rnti, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && cellGroupConfig != NULL); + instance_t f1inst = get_f1_gtp_instance(); cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList)); AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n"); @@ -178,6 +256,8 @@ static int handle_ue_context_drbs_release(int rnti, } if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { nr_rlc_release_entity(rnti, lcid); + if (f1inst >= 0) + newGtpuDeleteOneTunnel(f1inst, rnti, drb->rb_id); asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1); long *plcid = malloc(sizeof(*plcid)); AssertFatal(plcid != NULL, "out of memory\n"); @@ -557,6 +637,10 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) return; } + instance_t f1inst = get_f1_gtp_instance(); + if (f1inst >= 0) + newGtpuDeleteAllTunnels(f1inst, cmd->gNB_DU_ue_id); + if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ nr_mac_release_ue(mac, cmd->gNB_DU_ue_id);