diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index b1161e2b6da6da56d901f885121b1d3156d2266f..11fdd0e7bf9e46de3d715feb80cd64695b6f1324 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -27,6 +27,7 @@ #include "E1AP_E1AP-PDU.h" #include "E1AP_TransactionID.h" #include "E1AP_PriorityLevel.h" +#include "ngap_messages_types.h" #define E1AP_MAX_NUM_TRANSAC_IDS 4 #define E1AP_MAX_NUM_PLMNS 4 @@ -44,7 +45,7 @@ #define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp #define E1AP_PORT_NUMBER 25 -#define E1AP_SCTP_PPID 63 +#define E1AP_SCTP_PPID 64 typedef f1ap_net_ip_address_t e1ap_net_ip_address_t; @@ -101,6 +102,7 @@ typedef struct drb_to_setup_s { typedef struct qos_flow_to_setup_s { long id; + fiveQI_type_t fiveQI_type; long fiveQI; long qoSPriorityLevel; long packetDelayBudget; @@ -116,6 +118,9 @@ typedef struct DRB_nGRAN_to_setup_s { long defaultDRB; long sDAP_Header_UL; long sDAP_Header_DL; + long pDCP_SN_Size_UL; + long pDCP_SN_Size_DL; + long rLC_Mode; int numCellGroups; cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; int numQosFlow2Setup; @@ -138,7 +143,7 @@ typedef struct e1ap_bearer_setup_req_s { uint64_t gNB_cu_cp_ue_id; uint64_t cipheringAlgorithm; char encryptionKey[128]; - long bitRate; + long ueDlAggMaxBitRate; PLMN_ID_t servingPLMNid; long activityNotificationLevel; int numDRBs; diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index ca7dd0b0bb2c08ef0227c9a53db8a59863fc6650..6e9077088ee81ae5a786b329da07efcc4bb98312 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -262,9 +262,15 @@ typedef struct ngap_transport_layer_addr_s { dEST.length = sOURCE.length; \ } while (0) +typedef enum { + non_dynamic, + dynamic +} fiveQI_type_t; + typedef struct pdusession_level_qos_parameter_s { uint8_t qfi; uint64_t fiveQI; + fiveQI_type_t fiveQI_type; ngap_allocation_retention_priority_t allocation_retention_priority; } pdusession_level_qos_parameter_t; @@ -692,12 +698,21 @@ typedef struct ngap_pdusession_setup_req_s { /* gNB ue ngap id as initialized by NGAP layer */ uint32_t gNB_ue_ngap_id; + /* S-NSSAI */ + ngap_allowed_NSSAI_t allowed_nssai[8]; + /* Number of pdusession to be setup in the list */ uint8_t nb_pdusessions_tosetup; /* E RAB setup request */ pdusession_t pdusession_setup_params[NGAP_MAX_PDUSESSION]; + /* UE Uplink Aggregated Max Bitrates */ + uint64_t ueAggMaxBitRateUplink; + + /* UE Downlink Aggregated Max Bitrates */ + uint64_t ueAggMaxBitRateDownlink; + } ngap_pdusession_setup_req_t; typedef struct ngap_pdusession_setup_resp_s { diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index acdc6388a2fb808296f7b37b899cf80c87240800..60b0bed2d37e722be36a8c3bab73ac431d193d4f 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -175,6 +175,7 @@ int e1apCUUP_send_SETUP_REQUEST(instance_t instance) { ieC1->value.present = E1AP_GNB_CU_UP_E1SetupRequestIEs__value_PR_TransactionID; setup->transac_id = E1AP_get_next_transaction_identifier(); ieC1->value.choice.TransactionID = setup->transac_id; + LOG_I(E1AP, "Transaction ID of setup request %ld\n", setup->transac_id); /* mandatory */ /* c2. GNB_CU_ID (integer value) */ asn1cSequenceAdd(e1SetupUP->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupRequestIEs_t, ieC2); @@ -341,11 +342,17 @@ int e1apCUUP_handle_SETUP_RESPONSE(instance_t instance, E1AP_GNB_CU_UP_E1SetupResponseIEs_t *ie; /* transac_id */ - int transaction_id; + long transaction_id; + long old_transaction_id = getCxtE1(UPtype, instance)->setupReq.transac_id; F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_TransactionID, true); transaction_id = ie->value.choice.TransactionID; - LOG_D(E1AP, "gNB CU UP E1 setup response transaction ID: %d\n", transaction_id); + LOG_D(E1AP, "gNB CU UP E1 setup response transaction ID: %ld\n", transaction_id); + + if (old_transaction_id != transaction_id) + LOG_E(E1AP, "Transaction IDs do not match %ld != %ld\n", old_transaction_id, transaction_id); + + E1AP_free_transaction_identifier(transaction_id); /* do the required processing */ @@ -527,21 +534,23 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, ieC3->id = E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate; ieC3->criticality = E1AP_Criticality_reject; ieC3->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_BitRate; - asn_long2INTEGER(&ieC3->value.choice.BitRate, bearerCxt->bitRate); + asn_long2INTEGER(&ieC3->value.choice.BitRate, bearerCxt->ueDlAggMaxBitRate); /* mandatory */ /* c4. Serving PLMN */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC4); ieC4->id = E1AP_ProtocolIE_ID_id_Serving_PLMN; ieC4->criticality = E1AP_Criticality_ignore; ieC4->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity; - MCC_MNC_TO_PLMNID(bearerCxt->servingPLMNid.mcc, bearerCxt->servingPLMNid.mnc, bearerCxt->servingPLMNid.mnc_digit_length, &ieC4->value.choice.PLMN_Identity); + e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq; + PLMN_ID_t *servingPLMN = setup->plmns; // First PLMN is serving PLMN. TODO: Remove hard coding here + MCC_MNC_TO_PLMNID(servingPLMN->mcc, servingPLMN->mnc, servingPLMN->mnc_digit_length, &ieC4->value.choice.PLMN_Identity); /* mandatory */ /* Activity Notification Level */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC5); ieC5->id = E1AP_ProtocolIE_ID_id_ActivityNotificationLevel; ieC5->criticality = E1AP_Criticality_reject; ieC5->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel; - ieC5->value.choice.ActivityNotificationLevel = bearerCxt->activityNotificationLevel; + ieC5->value.choice.ActivityNotificationLevel = 2;// TODO: Remove hard coding /* mandatory */ /* */ asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC6); @@ -612,6 +621,10 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sDAP_Header_UL; ieC6_1_1->sDAP_Configuration.sDAP_Header_DL = j->sDAP_Header_DL; + ieC6_1_1->pDCP_Configuration.pDCP_SN_Size_UL = j->pDCP_SN_Size_UL; + ieC6_1_1->pDCP_Configuration.pDCP_SN_Size_DL = j->pDCP_SN_Size_DL; + ieC6_1_1->pDCP_Configuration.rLC_Mode = j->rLC_Mode; + for (cell_group_t *k=j->cellGroupList; k < j->cellGroupList+j->numCellGroups; k++) { asn1cSequenceAdd(ieC6_1_1->cell_Group_Information.list, E1AP_Cell_Group_Information_Item_t, ieC6_1_1_1); ieC6_1_1_1->cell_Group_ID = k->id; @@ -621,7 +634,7 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1); ieC6_1_1_1->qoS_Flow_Identifier = k->id; - if (0) { // non Dynamic 5QI + if (k->fiveQI_type == non_dynamic) { // non Dynamic 5QI ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI; asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI); non_Dynamic_5QI->fiveQI = k->fiveQI; @@ -825,7 +838,7 @@ int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, "ie->criticality != E1AP_Criticality_reject\n"); AssertFatal(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_BitRate, "ie->value.present != E1AP_BearerContextSetupRequestIEs__value_PR_BitRate\n"); - asn_INTEGER2long(&ie->value.choice.BitRate, &bearerCxt->bitRate); + asn_INTEGER2long(&ie->value.choice.BitRate, &bearerCxt->ueDlAggMaxBitRate); break; case E1AP_ProtocolIE_ID_id_Serving_PLMN: diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index bc5ae0789d641e6ca9f48e0a22278dc7ca6a1c55..dd92f9c100eaa2a622306d592c7693c4d9ec998b 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -96,6 +96,17 @@ E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { return genTransacId; } +void E1AP_free_transaction_identifier(E1AP_TransactionID_t id) { + + for (int i=0; i < E1AP_MAX_NUM_TRANSAC_IDS; i++) { + if (id == transacID[i]) { + transacID[i] = 0; + return; + } + } + LOG_E(E1AP, "Couldn't find transaction ID %ld in list\n", id); +} + int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) { DevAssert(pdu != NULL); diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 72c4accaecb3607c6f9e85b535488c092b4efd24..fdb3a96596107986e8a9a9443877a63146fb6767 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -41,4 +41,6 @@ int e1ap_assoc_id(E1_t type, instance_t instance); int e1ap_encode_send(E1_t type, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); void e1ap_common_init(); + +void E1AP_free_transaction_identifier(E1AP_TransactionID_t id); #endif /* E1AP_COMMON_H_ */ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 466c41957a32b8df03cf308b4f53788dc5444188..6687fb06b3751955fe5b0e7de182247a4d2a9097 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3876,7 +3876,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { } } -void rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { +int rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n"); gNB_RRC_INST *rrc = RC.nrrrc[0]; //TODO: remove hardcoding of RC index here @@ -3890,10 +3890,13 @@ void rrc_gNB_process_e1_setup_req(e1ap_setup_req_t *req, instance_t instance) { rrc->configuration.mnc[i] == req->plmns[i].mnc) { LOG_E(NR_RRC, "PLMNs received from CUUP (mcc:%d, mnc:%d) did not match with PLMNs in RRC (mcc:%d, mnc:%d)\n", req->plmns[i].mcc, req->plmns[i].mnc, rrc->configuration.mcc[i], rrc->configuration.mnc[i]); + return -1; } } itti_send_msg_to_task(TASK_CUCP_E1, instance, msg_p); + + return 0; } ///---------------------------------------------------------------------------------------------------------------/// diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 8f391417e0d991d518dd811e123981491def28dd..3c4e2dc269c752c532cec5c4d12e80cee0971620 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -58,6 +58,8 @@ #include "NGAP_Cause.h" #include "NGAP_CauseRadioNetwork.h" #include "f1ap_messages_types.h" +#include "E1AP_SDAP-Configuration.h" +#include "E1AP_PDCP-Configuration.h" extern RAN_CONTEXT_t RC; @@ -954,6 +956,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( ) //------------------------------------------------------------------------------ { + gNB_RRC_INST *rrc; uint16_t ue_initial_id; uint32_t gNB_ue_ngap_id; rrc_gNB_ue_context_t *ue_context_p = NULL; @@ -967,68 +970,147 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( ue_initial_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).ue_initial_id; gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); + rrc = RC.nrrrc[ctxt.module_id]; LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n", instance, msg_name, ue_initial_id, gNB_ue_ngap_id); - if (ue_context_p == NULL) { - MessageDef *msg_fail_p = NULL; - LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); - msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL); - NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); - return (-1); - } else { - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); - uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; - pdu_sessions_done = 0; + if (RC.nrrrc[ctxt.module_id]->cu_type == CPtype) { // E1 split CU-CP node + /* Configurations are referred from rrc_gNB_generate_dedicatedRRCReconfiguration() and + rrc_gNB_process_RRCReconfigurationComplete() + + At CU-CP we configure the E1 bearer context setup parameters (PDU sessions, DRBs and + QoS flows) same as in these functions. At CU-UP we create PDU Sessions and allocate DRBs. + */ + MessageDef *msg_p = NULL; + msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ); + e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p); + + bearer_req->gNB_cu_cp_ue_id = gNB_ue_ngap_id; + bearer_req->cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm; + memcpy(bearer_req->encryptionKey, ue_context_p->ue_context.kgnb, 128); + bearer_req->ueDlAggMaxBitRate = NGAP_PDUSESSION_SETUP_REQ(msg_p).ueAggMaxBitRateDownlink; + + bearer_req->numPDUSessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; + for (int i=0; i < bearer_req->numPDUSessions; i++) { + pdu_session_to_setup_t *pdu = bearer_req->pduSession + i; + pdu->sessionId = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].pdusession_id; + pdu->sessionType = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.pdu_session_type; + pdu->sst = NGAP_PDUSESSION_SETUP_REQ(msg_p).allowed_nssai[i].sST; + pdu->integrityProtectionIndication = 1; // Preferred. TODO: Remove hardcoding + pdu->confidentialityProtectionIndication = 1; // Preferred. TODO: Remove hardcoding + pdu->teId = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].gtp_teid; + memcpy(&pdu->tlAddress, + NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer, + sizeof(uint8_t)*20); + + pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding + for (int j=0; j < pdu->numDRB2Setup; j++) { + DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j; + drb->id = i + j; + drb->defaultDRB = E1AP_DefaultDRB_true; + + drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap); + drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap); + + drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18; + drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18; + + drb->rLC_Mode = E1AP_RLC_Mode_rlc_am; + + drb->numCellGroups = 1; // assume one cell group associated with a DRB + for (int k=0; k < drb->numCellGroups; k++) { + cell_group_t *cellGroup = drb->cellGroupList + k; + cellGroup->id = 0; // MCG + } - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); - for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { - if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) - continue; - ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; - create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; - create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1; - create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; - create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, - NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, - sizeof(uint8_t)*20); - create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length; - LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n", - i, - create_tunnel_req.outgoing_teid[pdu_sessions_done], - create_tunnel_req.pdusession_id[pdu_sessions_done]); - inde_list[pdu_sessions_done] = i; - pdu_sessions_done++; + drb->numQosFlow2Setup = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].nb_qos; + for (int k=0; k < drb->numQosFlow2Setup; k++) { + qos_flow_to_setup_t *qos = drb->qosFlows + k; - if(pdu_sessions_done >= nb_pdusessions_tosetup) { - break; + qos->id = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].qfi; + qos->fiveQI = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].fiveQI; + qos->fiveQI_type = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].fiveQI_type; + + qos->qoSPriorityLevel = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].allocation_retention_priority.priority_level; + qos->pre_emptionCapability = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_capability; + qos->pre_emptionVulnerability = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].qos[k].allocation_retention_priority.pre_emp_vulnerability; + } } } + itti_send_msg_to_task (TASK_CUCP_E1, ctxt.module_id, msg_p); + + } else { // Monolithic + if (ue_context_p == NULL) { + MessageDef *msg_fail_p = NULL; + LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); + msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL); + NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + // TODO add failure cause when defined! + itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); + return (-1); + } else { + memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; + pdu_sessions_done = 0; - ue_context_p->ue_context.nb_of_pdusessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; - ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; - ue_context_p->ue_context.amf_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).amf_ue_ngap_id; - create_tunnel_req.rnti = ue_context_p->ue_context.rnti; - create_tunnel_req.num_tunnels = pdu_sessions_done; + for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { + if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) + continue; + ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW; + ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; + create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; + create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1; + create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; + create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi; + memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, + NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, + sizeof(uint8_t)*20); + create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length; + LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n", + i, + create_tunnel_req.outgoing_teid[pdu_sessions_done], + create_tunnel_req.pdusession_id[pdu_sessions_done]); + inde_list[pdu_sessions_done] = i; + pdu_sessions_done++; - ret = gtpv1u_create_ngu_tunnel( - instance, - &create_tunnel_req, - &create_tunnel_resp); - if (ret != 0) { - LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_ng = 1; - ue_context_p->ue_context.ue_release_timer_thres_ng = 100; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ - // rrc_gNB_free_UE(ctxt.module_id,ue_context_p); - ue_context_p->ue_context.ul_failure_timer = 0; - return (0); + if(pdu_sessions_done >= nb_pdusessions_tosetup) { + break; + } + } + + ue_context_p->ue_context.nb_of_pdusessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; + ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; + ue_context_p->ue_context.amf_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).amf_ue_ngap_id; + create_tunnel_req.rnti = ue_context_p->ue_context.rnti; + create_tunnel_req.num_tunnels = pdu_sessions_done; + + ret = gtpv1u_create_ngu_tunnel( + instance, + &create_tunnel_req, + &create_tunnel_resp); + if (ret != 0) { + LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_ng = 1; + ue_context_p->ue_context.ue_release_timer_thres_ng = 100; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + // rrc_gNB_free_UE(ctxt.module_id,ue_context_p); + ue_context_p->ue_context.ul_failure_timer = 0; + return (0); + } + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + &ctxt, + &create_tunnel_resp, + &inde_list[0]); + ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup; + + // TEST + // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE; + // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0); + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p); + return(0); } nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( &ctxt, diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 35b152f1298ee2e7ab35fe57a2640e68673740ec..ebe86afe2a7e4afbd44b9ac21428088fd6623fba 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -1321,6 +1321,14 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, NGAP_PDUSESSION_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; NGAP_PDUSESSION_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; + /* UE Aggregated Maximum Bitrate */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate, true); + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateUL), + &NGAP_PDUSESSION_SETUP_REQ(message_p).ueAggMaxBitRateUplink); + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateDL), + &NGAP_PDUSESSION_SETUP_REQ(message_p).ueAggMaxBitRateDownlink); + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq, true); @@ -1334,9 +1342,13 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL; NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; + // PDU session ID item_p = (NGAP_PDUSessionResourceSetupItemSUReq_t *)ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i]; NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; + // S-NSSAI + OCTET_STRING_TO_INT32(&item_p->s_NSSAI.sST, NGAP_PDUSESSION_SETUP_REQ(message_p).allowed_nssai[i].sST); + OCTET_STRING_TO_INT32(item_p->s_NSSAI.sD, *NGAP_PDUSESSION_SETUP_REQ(message_p).allowed_nssai[i].sD); // check for the NAS PDU if (item_p->pDUSessionNAS_PDU->size > 0 ) { @@ -1422,10 +1434,14 @@ int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, /* Set the QOS informations */ NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI_type = non_dynamic; if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI = (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; } + } else if (qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_dynamic5QI) + { + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI_type = dynamic; } NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;