diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 81542cb9e5c0445c745a43e9678287c955c74fbc..891e05882364c30c00a6e1b388a0780beab2652f 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -35,6 +35,8 @@ #define E1AP_MAX_NUM_DRBS 4 #define E1AP_MAX_NUM_DRBS 4 #define E1AP_MAX_NUM_UP_PARAM 4 +#define E1AP_GTP_INST_N3 10 +#define E1AP_GTP_INST_F1U 11 #define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req #define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp @@ -75,6 +77,12 @@ typedef struct cell_group_s { long id; } cell_group_t; +typedef struct up_params_s { + in_addr_t tlAddress; + long teId; + int cell_group_id; +} up_params_t; + typedef struct drb_to_setup_s { long drbId; long pDCP_SN_Size_UL; @@ -115,6 +123,8 @@ typedef struct DRB_nGRAN_to_setup_s { long rLC_Mode; in_addr_t tlAddress; int teId; + int numDlUpParam; + up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM]; int numCellGroups; cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; int numQosFlow2Setup; @@ -135,10 +145,13 @@ typedef struct pdu_session_to_setup_s { int tl_port_dl; long numDRB2Setup; DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB]; + long numDRB2Modify; + DRB_nGRAN_to_setup_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB]; } pdu_session_to_setup_t; typedef struct e1ap_bearer_setup_req_s { uint64_t gNB_cu_cp_ue_id; + uint64_t gNB_cu_up_ue_id; rnti_t rnti; uint64_t cipheringAlgorithm; uint64_t integrityProtectionAlgorithm; @@ -151,13 +164,10 @@ typedef struct e1ap_bearer_setup_req_s { drb_to_setup_t DRBList[E1AP_MAX_NUM_DRBS]; int numPDUSessions; pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; + int numPDUSessionsMod; + pdu_session_to_setup_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS]; } e1ap_bearer_setup_req_t; -typedef struct up_params_s { - in_addr_t tlAddress; - long teId; -} up_params_t; - typedef struct drb_setup_s { int drbId; in_addr_t tlAddress; @@ -205,6 +215,8 @@ typedef struct e1ap_bearer_setup_resp_s { typedef struct e1ap_upcp_inst_s { uint32_t assoc_id; + instance_t gtpInstN3; + instance_t gtpInstF1U; e1ap_setup_req_t setupReq; e1ap_bearer_setup_req_t bearerSetupReq; e1ap_bearer_setup_resp_t bearerSetupResp; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index d366902b81a33df0e06a810dfc9a855c81d5a19e..40d89101287df642a279fb416a969f5ed504c6b7 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -40,7 +40,7 @@ e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = { { 0, 0, 0 }, /* gNBCUCPConfigurationUpdate */ { 0, 0, 0 }, /* E1Release */ { e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST, e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE, e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE }, /* bearerContextSetup */ - { 0, 0, 0 }, /* bearerContextModification */ + { e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST, 0, 0 }, /* bearerContextModification */ { 0, 0, 0 }, /* bearerContextModificationRequired */ { 0, 0, 0 }, /* bearerContextRelease */ { 0, 0, 0 }, /* bearerContextReleaseRequired */ @@ -1048,7 +1048,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance, AssertFatal(pdu->nG_DL_UP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel, "pdu->nG_DL_UP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n"); BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&pdu->nG_DL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress, - pduSetup->tlAddress); + pduSetup->tlAddress); OCTET_STRING_TO_INT32(&pdu->nG_DL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID, pduSetup->teId); } @@ -1059,6 +1059,24 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance, E1AP_DRB_Setup_Item_NG_RAN_t *drb = pdu->dRB_Setup_List_NG_RAN.list.array[j]; drbSetup->id = drb->dRB_ID; + + drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count; + for (int k=0; k < drb->uL_UP_Transport_Parameters.list.count; k++) { + up_params_t *UL_UP_param = drbSetup->UpParamList + k; + E1AP_UP_Parameters_Item_t *in_UL_UP_param = drb->uL_UP_Transport_Parameters.list.array[k]; + + AssertFatal(in_UL_UP_param->uP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel, + "in_UL_UP_param->uP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n"); + E1AP_GTPTunnel_t *gTPTunnel = in_UL_UP_param->uP_TNL_Information.choice.gTPTunnel; + if (gTPTunnel) { + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress, + UL_UP_param->tlAddress); + OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID, + UL_UP_param->teId); + } else { + AssertFatal(false, "gTPTunnel information in required\n"); + } + } } } break; @@ -1087,9 +1105,76 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance, */ int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - e1ap_bearer_setup_req_t *req) { - AssertFatal(false,"Not implemented yet\n"); - return -1; + e1ap_bearer_setup_req_t *bearerCxt) { + E1AP_E1AP_PDU_t pdu = {0}; + /* Create */ + /* 0. pdu Type */ + e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq; + if (!setup) { + LOG_E(E1AP, "got send_BEARER_CONTEXT_MODIFICATION_REQUEST on not established instance (%ld)\n", instance); + return -1; + } + + pdu.present = E1AP_E1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, msg); + msg->procedureCode = E1AP_ProcedureCode_id_bearerContextModification; + msg->criticality = E1AP_Criticality_reject; + msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest; + E1AP_BearerContextModificationRequest_t *out = &pdu.choice.initiatingMessage->value.choice.BearerContextModificationRequest; + /* mandatory */ + /* c1. gNB-CU-CP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC1); + ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID; + ieC1->criticality = E1AP_Criticality_reject; + ieC1->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID; + ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + /* mandatory */ + /* c2. gNB-CU-UP UE E1AP ID */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC2); + ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID; + ieC2->criticality = E1AP_Criticality_reject; + ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID; + ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id; + /* optional */ + /* */ + asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3); + ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest; + ieC3->criticality = E1AP_Criticality_reject; + ieC3->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest; + ieC3->value.choice.System_BearerContextModificationRequest.present = E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest; + E1AP_ProtocolIE_Container_4932P26_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P26_t)); + ieC3->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list; + asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextModificationRequest_t, msgNGRAN); + msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List; + msgNGRAN->criticality = E1AP_Criticality_reject; + msgNGRAN->value.present = E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List; + E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List; + for(pdu_session_to_setup_t *i=bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod+bearerCxt->numPDUSessionsMod; i++) { + asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Modify_Item_t, ieC3_1); + ieC3_1->pDU_Session_ID = i->sessionId; + + for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanModList; j < i->DRBnGRanModList+i->numDRB2Modify; j++) { + asn1cCalloc(ieC3_1->dRB_To_Modify_List_NG_RAN, drb2Mod_List); + asn1cSequenceAdd(drb2Mod_List->list, E1AP_DRB_To_Modify_Item_NG_RAN_t, drb2Mod); + drb2Mod->dRB_ID = j->id; + + if (j->numDlUpParam > 0) { + asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List); + for (up_params_t *k=j->DlUpParamList; k < j->DlUpParamList+j->numDlUpParam; k++) { + asn1cSequenceAdd(DL_UP_Param_List->list, E1AP_UP_Parameters_Item_t, DL_UP_Param); + DL_UP_Param->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel; + asn1cCalloc(DL_UP_Param->uP_TNL_Information.choice.gTPTunnel, gTPTunnel); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress); + INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID); + + DL_UP_Param->cell_Group_ID = k->cell_group_id; + } + } + } + } + + e1ap_encode_send(CPtype, instance, &pdu, 0, __func__); + return 0; } int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { @@ -1103,11 +1188,115 @@ int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { } int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance, - uint32_t assoc_id, - uint32_t stream, E1AP_E1AP_PDU_t *pdu) { - AssertFatal(false,"Not implemented yet\n"); - return -1; + e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance); + if (!e1_inst) { + LOG_E(E1AP, "got BEARER_CONTEXT_MODIFICATION_REQUEST on not established instance (%ld)\n", instance); + return -1; + } + + DevAssert(pdu != NULL); + AssertFatal(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage, + "pdu->present != E1AP_E1AP_PDU_PR_initiatingMessage\n"); + AssertFatal(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextModification, + "procedureCode != E1AP_ProcedureCode_id_bearerContextModification\n"); + AssertFatal(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject, + "criticality != E1AP_Criticality_reject\n"); + AssertFatal(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest, + "initiatingMessage->value.present != E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest\n"); + + E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest; + E1AP_BearerContextModificationRequestIEs_t *ie; + + MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); + + e1ap_bearer_setup_req_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg); + LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count); + + for (int i=0; i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + + switch(ie->id) { + case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID: + AssertFatal(ie->criticality == E1AP_Criticality_reject, + "ie->criticality != E1AP_Criticality_reject\n"); + AssertFatal(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID, + "ie->value.present != E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID\n"); + bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID: + AssertFatal(ie->criticality == E1AP_Criticality_reject, + "ie->criticality != E1AP_Criticality_reject\n"); + AssertFatal(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID, + "ie->value.present != E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID\n"); + bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID; + break; + + case E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest: + AssertFatal(ie->criticality == E1AP_Criticality_reject, + "ie->criticality != E1AP_Criticality_reject\n"); + AssertFatal(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest, + "ie->value.present != E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest\n"); + AssertFatal(ie->value.choice.System_BearerContextModificationRequest.present == + E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest, + "ie->value.choice.System_BearerContextSetupRequest.present !=" + "E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest\n"); + AssertFatal(ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest, + "nG_RAN_BearerContextModificationRequest is NULL\n"); + E1AP_ProtocolIE_Container_4932P26_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P26_t *) ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest; + E1AP_NG_RAN_BearerContextModificationRequest_t *msgNGRAN = msgNGRAN_list->list.array[0]; + AssertFatal(msgNGRAN_list->list.count == 1, "nG_RAN_BearerContextModificationRequest supports only 1 count for now\n"); + AssertFatal(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List, + "msgNGRAN->id (%ld) != E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List\n", msgNGRAN->id); + AssertFatal(msgNGRAN->value.present = + E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List, + "msgNGRAN->value.present != E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List\n"); + + E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2ModList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List; + bearerCxt->numPDUSessionsMod = pdu2ModList->list.count; + for (int i=0; i < pdu2ModList->list.count; i++) { + pdu_session_to_setup_t *pdu = bearerCxt->pduSessionMod + i; + E1AP_PDU_Session_Resource_To_Modify_Item_t *pdu2Mod = pdu2ModList->list.array[i]; + + pdu->sessionId = pdu2Mod->pDU_Session_ID; + + E1AP_DRB_To_Modify_List_NG_RAN_t *drb2ModList = pdu2Mod->dRB_To_Modify_List_NG_RAN; + pdu->numDRB2Modify = drb2ModList->list.count; + for (int j=0; j < drb2ModList->list.count; j++) { + DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanModList + j; + E1AP_DRB_To_Modify_Item_NG_RAN_t *drb2Mod = drb2ModList->list.array[j]; + + drb->id = drb2Mod->dRB_ID; + + E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters; + drb->numDlUpParam = dl_up_paramList->list.count; + for (int k=0; k < dl_up_paramList->list.count; k++) { + up_params_t *dl_up_param = drb->DlUpParamList + k; + E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k]; + if (dl_up_param_in->uP_TNL_Information.choice.gTPTunnel) { // Optional IE + AssertFatal(dl_up_param_in->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel, + "dl_up_param_in->uP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n"); + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->transportLayerAddress, + dl_up_param->tlAddress); + OCTET_STRING_TO_INT32(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->gTP_TEID, dl_up_param->teId); + } else { + AssertFatal(false, "gTPTunnel IE is missing. It is mandatory at this point\n"); + } + dl_up_param->cell_group_id = dl_up_param_in->cell_Group_ID; + } + } + } + break; + + default: + LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); + break; + } + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg); + return 0; } int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h index 6aa6f9918476833e09e101eb679f176e17a26ad6..5467f98b8fdd74ab34c3b32c0c4d8cc000251663 100644 --- a/openair2/E1AP/e1ap.h +++ b/openair2/E1AP/e1ap.h @@ -53,6 +53,9 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance, int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance, E1AP_E1AP_PDU_t *pdu); +int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance, + E1AP_E1AP_PDU_t *pdu); + void *E1AP_CUUP_task(void *arg); void *E1AP_CUCP_task(void *arg); diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index bc0a6d58df92fcf984450b1909b583edc8c0dca6..fc77a22c53a3084f18f3f6372a87481586751a92 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -51,11 +51,12 @@ void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) { if (type == CPtype) { AssertFatal(e1ap_cp_inst[instance] == NULL, "Double call to E1 CP instance %d\n", (int)instance); e1ap_cp_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t)); - memcpy(&e1ap_cp_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t)); } else if (type == UPtype) { AssertFatal(e1ap_up_inst[instance] == NULL, "Double call to E1 UP instance %d\n", (int)instance); e1ap_up_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t)); memcpy(&e1ap_up_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t)); + e1ap_up_inst[instance]->gtpInstN3 = E1AP_GTP_INST_N3; + e1ap_up_inst[instance]->gtpInstF1U = E1AP_GTP_INST_F1U; } else { AssertFatal(false, "Unknown CU type\n"); } @@ -121,6 +122,9 @@ int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) { case E1AP_ProcedureCode_id_bearerContextSetup: break; + case E1AP_ProcedureCode_id_bearerContextModification: + break; + default: LOG_E(E1AP, "Unsupported procedure code (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 26e632913f8b04af7ce78a73a1158c84bce8ff2f..46d6524a7a41a5f7b61eb37981aa8f2ac4b951e7 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -53,6 +53,10 @@ #include <E1AP_DRB-To-Setup-Item-NG-RAN.h> #include <E1AP_Cell-Group-Information-Item.h> #include <E1AP_PDU-Session-Resource-To-Setup-Item.h> +#include <E1AP_PDU-Session-Resource-To-Modify-List.h> +#include <E1AP_PDU-Session-Resource-To-Modify-Item.h> +#include <E1AP_DRB-To-Modify-List-NG-RAN.h> +#include <E1AP_DRB-To-Modify-Item-NG-RAN.h> #include <E1AP_GTPTunnel.h> #include <E1AP_Non-Dynamic5QIDescriptor.h> #include <E1AP_Dynamic5QIDescriptor.h> diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 4a406bfc8a5bf0ada2a537fbad2996691e88e2c8..b2c2d3a7aa8be7432853e5afc83beb9f9c7a8028 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3597,27 +3597,28 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch } static void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id) { - for (int i=0; i < req->numPDUSessions; i++) { - for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) { - DRB_nGRAN_to_setup_t *drb_p = req->pduSession[i].DRBnGRanList + j; + for (int i=0; i < req->numPDUSessionsMod; i++) { + for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { + DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j; transport_layer_addr_t newRemoteAddr; newRemoteAddr.length = 32; // IPv4 memcpy(newRemoteAddr.buffer, - &drb_p->tlAddress, + &drb_p->DlUpParamList[0].tlAddress, sizeof(in_addr_t)); GtpuUpdateTunnelOutgoingPair(instance, ue_id, (ebi_t)drb_p->id, - drb_p->teId, + drb_p->DlUpParamList[0].teId, newRemoteAddr); } } } void rrc_CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance) { - update_UL_UP_tunnel_info(req, instance, req->gNB_cu_cp_ue_id); + instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U; + update_UL_UP_tunnel_info(req, gtpInst, req->gNB_cu_cp_ue_id); // TODO: send bearer cxt mod response } @@ -3652,18 +3653,19 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c MessageDef *msg_e1 = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ); e1ap_bearer_setup_req_t *req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_e1); - req->numPDUSessions = ue_context_p->ue_context.nb_of_pdusessions; + req->numPDUSessionsMod = ue_context_p->ue_context.nb_of_pdusessions; req->gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id; req->rnti = ue_context_p->ue_context.rnti; - for (int i=0; i < req->numPDUSessions; i++) { - req->pduSession[i].numDRB2Setup = resp->drbs_to_be_setup_length; + 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->pduSession[i].DRBnGRanList + j; + DRB_nGRAN_to_setup_t *drb_e1 = req->pduSessionMod[i].DRBnGRanModList + j; drb_e1->id = drb_f1->drb_id; - drb_e1->tlAddress = drb_f1->up_dl_tnl[0].tl_address; - drb_e1->teId = drb_f1->up_dl_tnl[0].teid; + 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; } } @@ -4167,7 +4169,8 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0}; // GTP tunnel for UL - drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, instance); + instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstN3; + drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, gtpInst); MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, instance, E1AP_BEARER_CONTEXT_SETUP_RESP); @@ -4175,10 +4178,12 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; in_addr_t my_addr; - memcpy(&my_addr, - &getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address, - sizeof(my_addr)); - gNB_CU_create_up_ul_tunnel(resp, req, instance, req->gNB_cu_cp_ue_id, remote_port, my_addr); + inet_pton(AF_INET, + getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address, + &my_addr); + + gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U; + gNB_CU_create_up_ul_tunnel(resp, req, gtpInst, req->gNB_cu_cp_ue_id, remote_port, my_addr); resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; resp->numPDUSessions = req->numPDUSessions; @@ -4278,6 +4283,11 @@ void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req, instance_t instance // create ITTI msg and send to CUCP E1 task to send via SCTP // then in CUUP the function rrc_gNB_process_e1_bearer_context_setup_req + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti); + protocol_ctxt_t ctxt = {0}; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + + fill_DRB_configList(&ctxt, ue_context_p); MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ); e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t)); @@ -4487,6 +4497,11 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance); break; + case E1AP_BEARER_CONTEXT_MODIFICATION_REQ: + LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_MODIFICATION_REQ for instance %d\n", (int)instance); + rrc_CUUP_process_bearer_context_mod_req(&E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p), instance); + break; + default: LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break;