From 175fb1769a4fb81df41e82d7198890430fc4c203 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 13 Jun 2019 12:14:03 +0200 Subject: [PATCH 1/9] dual connectivity: preparatory work - basic version of x2ap_eNB_generate_senb_addition_request with dumb values - skeleton functions: - x2ap_eNB_handle_senb_addition_request - x2ap_eNB_handle_senb_addition_request_acknowledge - x2ap_eNB_handle_senb_addition_request_reject --- openair2/X2AP/x2ap_eNB_generate_messages.c | 98 ++++++++++++++++++++++ openair2/X2AP/x2ap_eNB_generate_messages.h | 3 + openair2/X2AP/x2ap_eNB_handler.c | 50 ++++++++++- 3 files changed, 150 insertions(+), 1 deletion(-) diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 38ebd732ac..fd0ff891b1 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -993,3 +993,101 @@ int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_ return ret; } + +int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p + /* TODO: pass needed parameters */) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SeNBAdditionRequest_t *out; + X2AP_SeNBAdditionRequest_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + /* Prepare the X2AP SeNB Addition Request message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SeNBAdditionRequest; + out = &pdu.choice.initiatingMessage.value.choice.SeNBAdditionRequest; + + /* id-MeNB-UE-X2AP-ID - mandatory - criticality reject */ + ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = 0; /* TODO */ + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* id-UE-SecurityCapabilities - conditional - criticality reject */ + /* TODO */ + + /* id-SeNBSecurityKey - conditional - criticality reject */ + /* TODO */ + + /* id-SeNBUEAggregateMaximumBitRate - mandatory - criticality reject */ + ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate; + if (asn_imax2INTEGER(&ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink, 0) != 0) { /* TODO: right value */ + LOG_E(X2AP, "%s:%d:%s: fatal asn1 error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if (asn_imax2INTEGER(&ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink, 0) != 0) { /* TODO: right value */ + LOG_E(X2AP, "%s:%d:%s: fatal asn1 error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* id-ServingPLMN - optional - criticality ignore */ + /* TODO */ + + /* id-E-RABs-ToBeAdded-List - mandatory - criticality reject */ + ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List; + /* TODO: set value of ie->value.choice.E_RABs_ToBeAdded_List.list */ + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* id-MeNBtoSeNBContainer - mandatory - criticality reject */ + ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer; + /* TODO: set value of ie->value.choice.MeNBtoSeNBContainer */ + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* id-CSGMembershipStatus - optional - criticality reject */ + /* TODO */ + + /* id-SeNB-UE-X2AP-ID - optional - criticality reject */ + /* TODO */ + + /* id-SeNB-UE-X2AP-ID-Extension - optional - criticality reject */ + /* TODO */ + + /* id-ExpectedUEBehaviour - optional - criticality ignore */ + /* TODO */ + + /* id-MeNB-UE-X2AP-ID-Extension - optional - criticality reject */ + /* TODO */ + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2AP SeNB Addition Request\n"); + abort(); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2SeNBAdditionRequest/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1); + + return ret; +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 1fcdf31f12..d545ee35b5 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -60,4 +60,7 @@ int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_ int x2_ue_id, x2ap_handover_cancel_cause_t cause); +int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p + /* TODO: pass needed parameters */); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 33fd9c5295..b8d0b299da 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -84,6 +84,24 @@ int x2ap_eNB_handle_handover_cancel (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_eNB_handle_senb_addition_request (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_eNB_handle_senb_addition_request_acknowledge (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */ @@ -105,7 +123,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* x2Release */ { 0, 0, 0 }, /* x2APMessageTransfer */ { 0, 0, 0 }, /* x2Removal */ - { 0, 0, 0 }, /* seNBAdditionPreparation */ + { x2ap_eNB_handle_senb_addition_request, x2ap_eNB_handle_senb_addition_request_acknowledge, x2ap_eNB_handle_senb_addition_request_reject }, /* seNBAdditionPreparation */ { 0, 0, 0 }, /* seNBReconfigurationCompletion */ { 0, 0, 0 }, /* meNBinitiatedSeNBModificationPreparation */ { 0, 0, 0 }, /* seNBinitiatedSeNBModification */ @@ -1073,3 +1091,33 @@ int x2ap_eNB_handle_handover_cancel (instance_t instance, return 0; } + +static +int x2ap_eNB_handle_senb_addition_request (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__); + return 0; +} + +static +int x2ap_eNB_handle_senb_addition_request_acknowledge (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__); + return 0; +} + +static +int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__); + return 0; +} From 3dee153067b18d2a8bb8330b23baf53fbf8b8456 Mon Sep 17 00:00:00 2001 From: matzakos Date: Sun, 16 Jun 2019 20:17:59 +0200 Subject: [PATCH 2/9] Dual connectivity: Basic implementation of x2ap_eNB_handle_senb_addition_request and x2ap_eNB_generate_senb_addition_request_ack --- openair2/COMMON/x2ap_messages_def.h | 3 + openair2/COMMON/x2ap_messages_types.h | 87 ++++++++-- openair2/X2AP/x2ap_eNB_generate_messages.c | 133 +++++++++++++++ openair2/X2AP/x2ap_eNB_generate_messages.h | 3 + openair2/X2AP/x2ap_eNB_handler.c | 183 ++++++++++++++++++++- 5 files changed, 395 insertions(+), 14 deletions(-) diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index c588753ca8..6c2d56a942 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -47,3 +47,6 @@ MESSAGE_DEF(X2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, x2ap_han /* handover messages X2AP <-> S1AP */ MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release) + +/*Senb bearer addition messages X2AP <-> RRC */ +MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_senb_addition_req_t , x2ap_senb_addition_req) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 5f2a95f576..e502191d2b 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -28,16 +28,16 @@ //-------------------------------------------------------------------------------------------// // Defines to access message fields. -#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req -#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req -#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp -#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req -#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack -#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf -#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind -#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release -#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel - +#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req +#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req +#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp +#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req +#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack +#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf +#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind +#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release +#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel +#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 @@ -236,4 +236,71 @@ typedef struct x2ap_handover_req_ack_s { uint32_t mme_ue_s1ap_id; } x2ap_handover_req_ack_t; +typedef struct x2ap_senb_addition_req_s { + + /* MeNB UE X2AP ID*/ + int x2_MeNB_UE_id; + + /*SCG Bearer option*/ + security_capabilities_t UE_security_capabilities; + + /*SCG Bearer option*/ + uint8_t SeNB_security_key[256]; + + /*SeNB UE aggregate maximum bitrate */ + ambr_t SeNB_ue_ambr; + + uint8_t total_nb_e_rabs_tobeadded; + + uint8_t nb_sCG_e_rabs_tobeadded; + + uint8_t nb_split_e_rabs_tobeadded; + + /*list of total e_rabs (SCG or split) to be added*/ + //e_rab_setup_t total_e_rabs_tobeadded[S1AP_MAX_E_RAB]; + + /* list of SCG e_rab to be added by RRC layers */ + e_rab_setup_t e_sCG_rabs_tobeadded[S1AP_MAX_E_RAB]; + + /* list of split e_rab to be added by RRC layers */ + e_rab_setup_t e_split_rabs_tobeadded[S1AP_MAX_E_RAB]; + + /* list of SCG e_rab to be added by RRC layers */ + e_rab_t e_sCG_rab_param[S1AP_MAX_E_RAB]; + + /* list of split e_rab to be added by RRC layers */ + e_rab_t e_split_rab_param[S1AP_MAX_E_RAB]; + + /*Used for the MeNB to SeNB Container to include the SCG-ConfigInfo as per 36.331*/ + uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; + + int rrc_buffer_size; + +}x2ap_senb_addition_req_t; + + + + +//Panos: Have to see what should be the additional/different elements comparing to handover req ack +typedef struct x2ap_senb_addition_req_ack_s { + + int MeNB_UE_X2_id; + + int SeNB_UE_X2_id; + + uint8_t nb_sCG_e_rabs_tobeadded; + + uint8_t nb_split_e_rabs_tobeadded; + + /* list of SCG e_rab to be added by RRC layers */ + e_rab_setup_t e_sCG_rabs_tobeadded[S1AP_MAX_E_RAB]; + + /* list of split e_rab to be added by RRC layers */ + e_rab_setup_t e_split_rabs_tobeadded[S1AP_MAX_E_RAB]; + + uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; + int rrc_buffer_size; + +} x2ap_senb_addition_req_ack_t; + #endif /* X2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index fd0ff891b1..0f93d879e8 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1091,3 +1091,136 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2 return ret; } + +//Panos: +int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack) +{ + + X2AP_X2AP_PDU_t pdu; + X2AP_SeNBAdditionRequestAcknowledge_t *out; + X2AP_SeNBAdditionRequestAcknowledge_IEs_t *ie; + X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *e_RABS_Admitted_ToBeAdded_ItemIEs; + X2AP_E_RABs_Admitted_ToBeAdded_Item_t *e_RABs_Admitted_ToBeAdded_Item; + int ue_id; + int ue_id_MeNB; + int ue_id_SeNB; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + //Panos: The fact that we have separate IDs here is because the ID for a specific UE might be different + //between the 2 eNBs? + //ue_id = x2ap_addition_req_ack->x2_id_target; //Panos: change name to master_x2... + //id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + //id_target = ue_id; + + /* Prepare the X2AP addition req. ack. message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation; + //Panos: What does the criticality indicate here? + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SeNBAdditionRequestAcknowledge; + out = &pdu.choice.successfulOutcome.value.choice.SeNBAdditionRequestAcknowledge; + + /* mandatory */ + ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = 0; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SeNB_UE_X2AP_ID; + //Panos: Why for the X2_HANDOVER_REQ_ACK here the criticality is ignore whereas in the specs it is reject? + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1; + ie->value.choice.UE_X2AP_ID_1 = 0; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_List; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_List; + + { + // SCG bearers to be added + for (int i=0;inb_sCG_e_rabs_tobeadded;i++) { + e_RABS_Admitted_ToBeAdded_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t)); + e_RABS_Admitted_ToBeAdded_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item; + e_RABS_Admitted_ToBeAdded_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_Admitted_ToBeAdded_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item; + e_RABs_Admitted_ToBeAdded_Item = &e_RABS_Admitted_ToBeAdded_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_Item; + { + e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_ID = x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].e_rab_id; + INT32_TO_OCTET_STRING(x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].gtp_teid, &e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.gTP_TEID); + + e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.length/8); + e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.length%8; + e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf = + calloc(1,e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); + + memcpy (e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, + x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.buffer, + e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_List.list, e_RABS_Admitted_ToBeAdded_ItemIEs); + } + + // Split bearers to be added + for (int i=0;inb_split_e_rabs_tobeadded;i++) { + e_RABS_Admitted_ToBeAdded_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t)); + e_RABS_Admitted_ToBeAdded_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item; + e_RABS_Admitted_ToBeAdded_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_Admitted_ToBeAdded_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item; + e_RABs_Admitted_ToBeAdded_Item = &e_RABS_Admitted_ToBeAdded_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_Item; + { + e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.e_RAB_ID = x2ap_addition_req_ack->e_split_rabs_tobeadded[i].e_rab_id; + INT32_TO_OCTET_STRING(x2ap_addition_req_ack->e_split_rabs_tobeadded[i].gtp_teid, &e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.gTP_TEID); + + e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.length/8); + e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.length%8; + e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.buf = + calloc(1,e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size); + + memcpy (e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.buf, + x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.buffer, + e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_List.list, e_RABS_Admitted_ToBeAdded_ItemIEs); + } + + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SeNBtoMeNBContainer; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_SeNBtoMeNBContainer; + + OCTET_STRING_fromBuf(&ie->value.choice.SeNBtoMeNBContainer, (char*) x2ap_addition_req_ack->rrc_buffer, x2ap_addition_req_ack->rrc_buffer_size); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode SeNB addition response\n"); + abort(); + return -1; + } + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1); + + return ret; +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index d545ee35b5..672ffdb36e 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -63,4 +63,7 @@ int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p /* TODO: pass needed parameters */); +int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index b8d0b299da..7d22f98cc8 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -90,8 +90,9 @@ int x2ap_eNB_handle_senb_addition_request (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); + static -int x2ap_eNB_handle_senb_addition_request_acknowledge (instance_t instance, +int x2ap_eNB_handle_senb_addition_request_ack (instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu); @@ -123,7 +124,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* x2Release */ { 0, 0, 0 }, /* x2APMessageTransfer */ { 0, 0, 0 }, /* x2Removal */ - { x2ap_eNB_handle_senb_addition_request, x2ap_eNB_handle_senb_addition_request_acknowledge, x2ap_eNB_handle_senb_addition_request_reject }, /* seNBAdditionPreparation */ + { x2ap_eNB_handle_senb_addition_request, x2ap_eNB_handle_senb_addition_request_ack, x2ap_eNB_handle_senb_addition_request_reject }, /* seNBAdditionPreparation */ { 0, 0, 0 }, /* seNBReconfigurationCompletion */ { 0, 0, 0 }, /* meNBinitiatedSeNBModificationPreparation */ { 0, 0, 0 }, /* seNBinitiatedSeNBModification */ @@ -1092,18 +1093,191 @@ int x2ap_eNB_handle_handover_cancel (instance_t instance, return 0; } + static int x2ap_eNB_handle_senb_addition_request (instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu) { - printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__); + + X2AP_SeNBAdditionRequest_t *x2SeNBAdditionRequest; + X2AP_SeNBAdditionRequest_IEs_t *ie; + + X2AP_E_RABs_ToBeAdded_ItemIEs_t *e_RABS_ToBeAdded_ItemIEs; + X2AP_E_RABs_ToBeAdded_Item_t *e_RABs_ToBeAdded_Item; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + + DevAssert (pdu != NULL); + x2SeNBAdditionRequest = &pdu->choice.initiatingMessage.value.choice.SeNBAdditionRequest; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 senb addition request on stream == 0\n"); + /* TODO: send a x2 failure response */ + return 0; + } + + X2AP_DEBUG ("Received a new X2 senb addition request\n"); + + //Panos: Do we need this for this message? Where is the x2ap_eNB_data used? + /*x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL);*/ + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_SENB_ADDITION_REQ); + + /*MeNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + //Panos: Here not sure which UE ID should be allocated to be forwarded to RRC... + /* allocate a new X2AP UE ID */ + /*ue_id = x2ap_allocate_new_id(&instance_p->id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + exit(1); + } + + x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id); + x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET);*/ + + //For now we hardcode both MeNB and SeNB UE IDs values + X2AP_SENB_ADDITION_REQ(msg).x2_MeNB_UE_id = 0; + + /* UESecurityCapabilities is specific to SCGBearerOption.*/ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, + X2AP_ProtocolIE_ID_id_UE_SecurityCapabilities, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + + X2AP_SENB_ADDITION_REQ(msg).UE_security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); + X2AP_SENB_ADDITION_REQ(msg).UE_security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); + + + /* SeNBSecurityKey is specific to SCGBearerOption.*/ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, + X2AP_ProtocolIE_ID_id_SeNBSecurityKey, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + memcpy(X2AP_SENB_ADDITION_REQ(msg).SeNB_security_key, + &ie->value.choice.SeNBSecurityKey.buf, + ie->value.choice.SeNBSecurityKey.size); + + /* SeNB to UE Aggregate Maximum Bit Rate */ + //Panos: SeNBUEAggregateMaximumBitRate: should it be added? It is not active in handover_req + /*X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, + X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate, true);*/ + + + /* E-RABs_To Be Added List */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, + X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + if (ie->value.choice.E_RABs_ToBeAdded_List.list.count > 0) { + + X2AP_SENB_ADDITION_REQ(msg).total_nb_e_rabs_tobeadded = ie->value.choice.E_RABs_ToBeAdded_List.list.count; + int sCG_Bearers_cnt = 0; + int split_Bearers_cnt = 0; + for (int i=0;ivalue.choice.E_RABs_ToBeAdded_List.list.count;i++) { + e_RABS_ToBeAdded_ItemIEs = (X2AP_E_RABs_ToBeAdded_ItemIEs_t *) ie->value.choice.E_RABs_ToBeAdded_List.list. array[i]; + e_RABs_ToBeAdded_Item = &e_RABS_ToBeAdded_ItemIEs->value.choice.E_RABs_ToBeAdded_Item; + + if(e_RABs_ToBeAdded_Item->present == X2AP_E_RABs_ToBeAdded_Item_PR_sCG_Bearer){ + + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].e_rab_id = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_ID; + + memcpy(X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].eNB_addr.buffer, + e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, + e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); + + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].eNB_addr.length = + e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; + + OCTET_STRING_TO_INT32(&e_RABs_ToBeAdded_Item->choice.sCG_Bearer.s1_UL_GTPtunnelEndpoint.gTP_TEID, + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rabs_tobeadded[sCG_Bearers_cnt].gtp_teid); + + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.qci = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.qCI; + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.allocation_retention_priority.priority_level = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; + X2AP_SENB_ADDITION_REQ(msg).e_sCG_rab_param[sCG_Bearers_cnt].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability; + sCG_Bearers_cnt++; + } + else if(e_RABs_ToBeAdded_Item->present == X2AP_E_RABs_ToBeAdded_Item_PR_split_Bearer){ + X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].e_rab_id = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_ID; + + memcpy(X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].eNB_addr.buffer, + e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.buf, + e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.size); + + X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].eNB_addr.length = + e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.transportLayerAddress.bits_unused; + + OCTET_STRING_TO_INT32(&e_RABs_ToBeAdded_Item->choice.split_Bearer.meNB_GTPtunnelEndpoint.gTP_TEID, + X2AP_SENB_ADDITION_REQ(msg).e_split_rabs_tobeadded[split_Bearers_cnt].gtp_teid); + + X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.qci = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.qCI; + X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.allocation_retention_priority.priority_level = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; + X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; + X2AP_SENB_ADDITION_REQ(msg).e_split_rab_param[split_Bearers_cnt].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeAdded_Item->choice.split_Bearer.e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability; + split_Bearers_cnt++; + } + } + + } + else { + X2AP_ERROR ("Can't decode the e_RABs_ToBeAdded_List \n"); + } + + /*MeNB to SeNB Container */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, + X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_MeNBtoSeNBContainer_t *c = &ie->value.choice.MeNBtoSeNBContainer; + + if (c->size > 1024) + { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } + + memcpy(X2AP_SENB_ADDITION_REQ(msg).rrc_buffer, c->buf, c->size); + X2AP_SENB_ADDITION_REQ(msg).rrc_buffer_size = c->size; + + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + return 0; } static -int x2ap_eNB_handle_senb_addition_request_acknowledge (instance_t instance, +int x2ap_eNB_handle_senb_addition_request_ack (instance_t instance, uint32_t assoc_id, uint32_t stream, X2AP_X2AP_PDU_t *pdu) @@ -1112,6 +1286,7 @@ int x2ap_eNB_handle_senb_addition_request_acknowledge (instance_t instance, return 0; } + static int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, uint32_t assoc_id, From 2adf459f6e4a04ec1cec2b0e9617f1b5dcfcbc1b Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 2 Jul 2019 17:34:21 +0200 Subject: [PATCH 3/9] Update X2AP to Rel.15 to support EN-DC X2 signaling for 5G Non-standalone --- cmake_targets/CMakeLists.txt | 1 - openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1 | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index dee34ef05d..732cfd289e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -469,7 +469,6 @@ endif(${X2AP_RELEASE} STREQUAL "R8") add_definitions(-DX2AP_VERSION=${X2AP_VERSION}) set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${X2AP_RELEASE}) set(X2AP_C_DIR ${asn1_generated_dir}/X2AP_${X2AP_RELEASE}) - # Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}" "X2AP_" -fno-include-deps RESULT_VARIABLE ret) diff --git a/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1 b/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1 index 04de5ca5c5..e8a053a12c 100644 --- a/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1 +++ b/openair2/X2AP/MESSAGES/ASN1/R15/x2ap-15.1.0.asn1 @@ -4010,7 +4010,7 @@ NRNeighbour-Information-ExtIEs X2AP-PROTOCOL-EXTENSION ::= { ... } -CellAssistanceInformationĀ ::= CHOICE { +CellAssistanceInformation ::= CHOICE { limited-list Limited-list, full-list ENUMERATED {allServedNRcells, ...}, ... @@ -6094,7 +6094,7 @@ SgNBResourceCoordinationInformationExtIEs X2AP-PROTOCOL-EXTENSION ::= { ... } -SgNB-UE-X2AP-IDĀ ::= INTEGER (0..4294967295) +SgNB-UE-X2AP-ID ::= INTEGER (0..4294967295) SIPTOBearerDeactivationIndication ::= ENUMERATED { true, From 8234afe8c54d724d9c25b42fbfe1455f7bb198d3 Mon Sep 17 00:00:00 2001 From: matzakos Date: Mon, 15 Jul 2019 12:55:14 +0200 Subject: [PATCH 4/9] ENDC for 5G NSA support (preparatory work): Basic implementation of x2ap_eNB_generate_ENDC_x2_setup_request() and x2ap_gNB_handle_ENDC_x2_setup_request() --- openair2/X2AP/x2ap_eNB_generate_messages.c | 125 ++++++++++++++++ openair2/X2AP/x2ap_eNB_generate_messages.h | 2 + openair2/X2AP/x2ap_eNB_handler.c | 160 ++++++++++++++++++++- 3 files changed, 286 insertions(+), 1 deletion(-) diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 0f93d879e8..422f5904f6 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1224,3 +1224,128 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p return ret; } + +int x2ap_eNB_generate_ENDC_x2_setup_request( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_ENDCX2SetupRequest_t *out; + X2AP_ENDCX2SetupRequest_IEs_t *ie; + X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC; + X2AP_PLMN_Identity_t *plmn; + ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_endcX2Setup; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_ENDCX2SetupRequest; + out = &pdu.choice.initiatingMessage.value.choice.ENDCX2SetupRequest; + + ie = (X2AP_ENDCX2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup; + ie->value.present = X2AP_ENDCX2SetupRequest_IEs__value_PR_InitiatingNodeType_EndcX2Setup; + ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_eNB; + + ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t)); + ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID; + ie_ENB_ENDC->criticality = X2AP_Criticality_reject; + ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_GlobalENB_ID; + ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present = X2AP_ENB_ID_PR_macro_eNB_ID; + MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id, + &ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID); + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie_ENB_ENDC->value.choice.GlobalENB_ID.pLMN_Identity); + + ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC); + + ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t)); + ie_ENB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList; + ie_ENB_ENDC->criticality = X2AP_Criticality_reject; + ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList; + + { + for (int i = 0; inum_cc; i++){ + servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedEUTRAcellsENDCX2ManagementList__Member)); + { + servedCellMember->servedEUTRACellInfo.pCI = instance_p->Nid_cell[i]; + + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &servedCellMember->servedEUTRACellInfo.cellId.pLMN_Identity); + MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0, + &servedCellMember->servedEUTRACellInfo.cellId.eUTRANcellIdentifier); + + INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedEUTRACellInfo.tAC); + plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); + { + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + ASN_SEQUENCE_ADD(&servedCellMember->servedEUTRACellInfo.broadcastPLMNs.list, plmn); + } + + if (instance_p->frame_type[i] == FDD) { + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; + switch (instance_p->N_RB_DL[i]) { + case 6: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } + } + else { + AssertFatal(0,"X2Setuprequest not supported for TDD!"); + } + } + ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list, ie_ENB_ENDC); + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 setup request\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 672ffdb36e..eb5b7f2449 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -66,4 +66,6 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2 int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack); +int x2ap_eNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 7d22f98cc8..7e46be024e 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -103,6 +103,11 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */ @@ -131,7 +136,20 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, /* meNBinitiatedSeNBRelease */ { 0, 0, 0 }, /* seNBinitiatedSeNBRelease */ { 0, 0, 0 }, /* seNBCounterCheck */ - { 0, 0, 0 } /* retrieveUEContext */ + { 0, 0, 0 }, /* retrieveUEContext */ + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { x2ap_gNB_handle_ENDC_x2_setup_request, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 } }; char *x2ap_direction2String(int x2ap_dir) { @@ -433,6 +451,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); } + static int x2ap_eNB_handle_x2_setup_response(instance_t instance, uint32_t assoc_id, @@ -1296,3 +1315,142 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance, printf("%s:%d:%s:TODO\n", __FILE__, __LINE__, __FUNCTION__); return 0; } + +int +x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_ENDCX2SetupRequest_t *x2_ENDC_SetupRequest; + X2AP_ENDCX2SetupRequest_IEs_t *ie; + X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC; + ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + uint32_t eNB_id = 0; + + DevAssert (pdu != NULL); + x2_ENDC_SetupRequest = &pdu->choice.initiatingMessage.value.choice.ENDCX2SetupRequest; + + /* + * We received a new valid X2 Setup Request on a stream != 0. + * * * * This should not happen -> reject eNB x2 setup request. + */ + + if (stream != 0) { + X2AP_ERROR("Received new x2 setup request on stream != 0\n"); + /* + * Send a x2 setup failure with protocol cause unspecified + */ + // Panos: Here we should be calling an ENDC specific setup_failure function instead + return x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + } + + X2AP_DEBUG("Received a new X2 setup request\n"); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupRequest_IEs_t, ie, x2_ENDC_SetupRequest, + X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup, true); + + + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } else { + if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count > 0) { + //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest + //message or the ie to which there are more nested information elements? + for (int i=0; ivalue.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.count;i++) { + + ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i]; + if (ie_ENB_ENDC == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_GlobalENB_ID) { + if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) { + // Home eNB ID = 28 bits + uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf; + if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { + //TODO: handle case were size != 28 -> notify ? reject ? + } + eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); + X2AP_DEBUG("Home eNB id: %07x\n", eNB_id); + } else { + // Macro eNB = 20 bits + uint8_t *eNB_id_buf = ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; + if (ie_ENB_ENDC->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { + //TODO: handle case were size != 20 -> notify ? reject ? + } + eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); + X2AP_DEBUG("macro eNB id: %05x\n", eNB_id); + } + X2AP_DEBUG("Adding eNB to the list of associated eNBs\n"); + if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (eNB_id)) == NULL) { + /* + * eNB has not been found in list of associated eNB, + * * * * Add it to the tail of list and initialize data + */ + if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { + /* + * ?? + */ + return -1; + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + x2ap_eNB_data->eNB_id = eNB_id; + } + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + + /* + * eNB has been found in list, consider the x2 setup request as a reset connection, + * * * * reseting any previous UE state if sctp association is != than the previous one + */ + if (x2ap_eNB_data->assoc_id != assoc_id) { + /* + * ??: Send an overload cause... + */ + X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id); + + // Panos: Here we should be calling an ENDC specific setup_failure function instead + x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + return -1; + } + /* + * * TODO: call the reset procedure + */ + } + } + else if (ie_ENB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedEUTRAcellsENDCX2ManagementList){ + if (ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count > 0) { + x2ap_eNB_data->num_cc = ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.count; + for (int i=0; ivalue.choice.ServedEUTRAcellsENDCX2ManagementList.list.count;i++) { + servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list.array[i]; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedEUTRACellInfo.pCI; + } + } + } + } + } + } + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + // Panos: Here we should be calling an ENDC specific setup response function + return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); +} + From e7d51624002624653b3c5fe793ee35e67159d8cf Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 15 Jul 2019 17:02:54 +0200 Subject: [PATCH 5/9] ENDC: Minor addition in x2ap decoder --- openair2/X2AP/x2ap_eNB_decoder.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 3604aa03c8..2bf9898436 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -59,6 +59,10 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); break; + case X2AP_ProcedureCode_id_endcX2Setup: + X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n"); + break; + default: X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage.procedureCode); From d605e5ffc3be52e4d7798731f14e98ed8e5e13d1 Mon Sep 17 00:00:00 2001 From: matzakos Date: Fri, 19 Jul 2019 12:08:54 +0200 Subject: [PATCH 6/9] ENDC for 5G NSA support: Basic implementation of x2ap_gNB_generate_ENDC_x2_setup_response() and x2ap_gNB_handle_ENDC_x2_setup_response() --- openair2/X2AP/x2ap_eNB.c | 3 +- openair2/X2AP/x2ap_eNB_decoder.c | 4 +- openair2/X2AP/x2ap_eNB_defs.h | 6 + openair2/X2AP/x2ap_eNB_generate_messages.c | 144 +++++++++++++++++++ openair2/X2AP/x2ap_eNB_generate_messages.h | 2 + openair2/X2AP/x2ap_eNB_handler.c | 156 ++++++++++++++++++++- 6 files changed, 311 insertions(+), 4 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 8b11e469b2..54b0020296 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -151,7 +151,8 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa printf("x2ap_eNB_handle_sctp_association_resp at 4\n"); dump_trees(); /* Prepare new x2 Setup Request */ - x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p); + x2ap_eNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p); + //x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p); } static diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 2bf9898436..de9e773761 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -60,8 +60,8 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) break; case X2AP_ProcedureCode_id_endcX2Setup: - X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n"); - break; + X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n"); + break; default: X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index 03d8216b56..6ab62ebf98 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -175,6 +175,12 @@ typedef struct x2ap_eNB_instance_s { uint32_t fdd_earfcn_UL[MAX_NUM_CCs]; uint32_t subframeAssignment[MAX_NUM_CCs]; uint32_t specialSubframe[MAX_NUM_CCs]; + +//#ifdef Rel15 + uint32_t tdd_nRARFCN[MAX_NUM_CCs]; + int16_t nr_SCS[MAX_NUM_CCs]; +//#endif + int num_cc; net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS]; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 422f5904f6..2a9406b632 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1225,9 +1225,11 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p return ret; } +/*setup request message from an eNB to a gNB*/ int x2ap_eNB_generate_ENDC_x2_setup_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) { + printf("In x2ap_eNB_generate_ENDC_x2_setup_request \n"); X2AP_X2AP_PDU_t pdu; X2AP_ENDCX2SetupRequest_t *out; X2AP_ENDCX2SetupRequest_IEs_t *ie; @@ -1349,3 +1351,145 @@ int x2ap_eNB_generate_ENDC_x2_setup_request( return ret; } + + +/*setup request message from an eNB to a gNB*/ +int x2ap_gNB_generate_ENDC_x2_setup_response( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_ENDCX2SetupResponse_t *out; + X2AP_ENDCX2SetupResponse_IEs_t *ie; + X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *ie_GNB_ENDC; + X2AP_PLMN_Identity_t *plmn; + ServedNRcellsENDCX2ManagementList__Member *servedCellMember; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.ENDCX2SetupResponse; + + ie = (X2AP_ENDCX2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupResponse_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup; + ie->value.present = X2AP_ENDCX2SetupResponse_IEs__value_PR_RespondingNodeType_EndcX2Setup; + ie->value.choice.RespondingNodeType_EndcX2Setup.present = X2AP_RespondingNodeType_EndcX2Setup_PR_respond_en_gNB; + + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t)); + ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_Globalen_gNB_ID; + ie_GNB_ENDC->criticality = X2AP_Criticality_reject; + ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_GlobalGNB_ID; + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.present = X2AP_GNB_ID_PR_gNB_ID; + + INT32_TO_OCTET_STRING(instance_p->eNB_id, + &ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID); + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity); + + ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC); + + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqAckIEs_t)); + ie_GNB_ENDC->id = X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList; + ie_GNB_ENDC->criticality = X2AP_Criticality_reject; + ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqAckIEs__value_PR_ServedNRcellsENDCX2ManagementList; + + { + for (int i = 0; inum_cc; i++){ + servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member)); + { + servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i]; + + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id, + &servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier); + + plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); + { + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); + ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn); + } + + if (instance_p->frame_type[i] == TDD) { + servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_ARFCN = instance_p->tdd_nRARFCN[i]; + /*Missing addition of Frequency Band List item here, can't find it... */ + switch (instance_p->N_RB_DL[i]) { + case 50: + //This is not correct. Just to be able to test X2 only using an eNB instead of gNB + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51; + break; + case 93 : + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93; + break; + case 106: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106; + break; + case 121: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121; + break; + + /*More cases to be added */ + + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } + + instance_p->nr_SCS[i] = 30; // Hardcoded for now. Normally this should originate from the gNB config file + switch (instance_p->nr_SCS[i]) { + case 15: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs15; + break; + case 30: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs30; + break; + case 60: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs60; + break; + case 120: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRSCS = X2AP_NRSCS_scs120; + break; + default: + AssertFatal(0,"Failed: Check value for nr_SCS"); + break; + } + } + else { + AssertFatal(0,"nr_X2Setupresponse not supported for FDD!"); + } + /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */ + INT16_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); + + } + ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list, ie_GNB_ENDC); + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 setup request\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index eb5b7f2449..6b0cd9c2da 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -68,4 +68,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p int x2ap_eNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); +int x2ap_gNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 7e46be024e..55d09e45b5 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -108,6 +108,13 @@ int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +int +x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + + /* Handlers matrix. Only eNB related procedure present here */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */ @@ -146,7 +153,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, - { x2ap_gNB_handle_ENDC_x2_setup_request, 0, 0 }, + { x2ap_gNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } @@ -1332,6 +1339,7 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, x2ap_eNB_data_t *x2ap_eNB_data; uint32_t eNB_id = 0; + x2ap_eNB_data = NULL; DevAssert (pdu != NULL); x2_ENDC_SetupRequest = &pdu->choice.initiatingMessage.value.choice.ENDCX2SetupRequest; @@ -1445,6 +1453,10 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, } } } + else { + X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__); + return -1; + } } instance_p = x2ap_eNB_get_instance(instance); @@ -1454,3 +1466,145 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); } +int +x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_ENDCX2SetupResponse_t *x2_ENDC_SetupResponse; + X2AP_ENDCX2SetupResponse_IEs_t *ie; + X2AP_En_gNB_ENDCX2SetupReqAckIEs_t *ie_GNB_ENDC; + ServedNRcellsENDCX2ManagementList__Member *servedCellMember; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + uint32_t gNB_id = 0; + + x2ap_eNB_data = NULL; + DevAssert (pdu != NULL); + x2_ENDC_SetupResponse = &pdu->choice.successfulOutcome.value.choice.ENDCX2SetupResponse; + + /* + * We received a new valid X2 Setup Request on a stream != 0. + * * * * This should not happen -> reject eNB x2 setup request. + */ + + if (stream != 0) { + X2AP_ERROR("Received new x2 setup request on stream != 0\n"); + /* + * Send a x2 setup failure with protocol cause unspecified + */ + // Panos: Here we should be calling an ENDC specific setup_failure function instead + return x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + } + + X2AP_DEBUG("Received a new X2 setup request\n"); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_ENDCX2SetupResponse_IEs_t, ie, x2_ENDC_SetupResponse, + X2AP_ProtocolIE_ID_id_RespondingNodeType_EndcX2Setup, true); + + + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } else { + if (ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count > 0) { + //Panos: Here the container parameter in X2AP_FIND_PROTOCOLIE_BY_ID should be the x2_ENDC_SetupRequest + //message or the ie to which there are more nested information elements? + for (int i=0; ivalue.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.count;i++) { + + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_en_gNB.list.array[i]; + if (ie_GNB_ENDC == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_Globalen_gNB_ID) { + if (ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.size!= 28) { + //TODO: handle case were size != 28 -> notify ? reject ? + } + OCTET_STRING_TO_INT32(&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID,gNB_id); + X2AP_DEBUG("gNB id: %07x\n", gNB_id); + + X2AP_DEBUG("Adding gNB to the list of associated gNBs\n"); + if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (gNB_id)) == NULL) { + /* + * eNB has not been found in list of associated eNB, + * * * * Add it to the tail of list and initialize data + */ + if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { + /* + * ?? + */ + return -1; + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + x2ap_eNB_data->eNB_id = gNB_id; + } + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + + /* + * eNB has been found in list, consider the x2 setup request as a reset connection, + * * * * reseting any previous UE state if sctp association is != than the previous one + */ + if (x2ap_eNB_data->assoc_id != assoc_id) { + /* + * ??: Send an overload cause... + */ + X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", gNB_id, x2ap_eNB_data->assoc_id, assoc_id); + + // Panos: Here we should be calling an ENDC specific setup_failure function instead + x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + return -1; + } + /* + * * TODO: call the reset procedure + */ + } + } + else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList){ + if (ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count > 0) { + x2ap_eNB_data->num_cc = ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count; + for (int i=0; ivalue.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) { + servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i]; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI; + } + } + } + } + } + else { + X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__); + return -1; + } + } + + /* Optionaly set the target eNB name */ + + /* The association is now ready as source and target eNBs know parameters of each other. + * Mark the association as connected. + */ + x2ap_eNB_data->state = X2AP_ENB_STATE_READY; + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + instance_p->x2_target_enb_associated_nb ++; + x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0); + + return 0; +} + + From 81c5da5f2fe89c492334e03f0e1856a654d6f902 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 23 Jul 2019 19:15:32 +0200 Subject: [PATCH 7/9] ENDC X2AP: Corrections at setup generation message and logs addition --- openair2/X2AP/x2ap_eNB_encoder.c | 4 ++-- openair2/X2AP/x2ap_eNB_generate_messages.c | 27 ++++++++++++++++++---- openair2/X2AP/x2ap_eNB_handler.c | 3 ++- openair3/UTILS/conversions.h | 20 ++++++++++++++++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB_encoder.c b/openair2/X2AP/x2ap_eNB_encoder.c index 8b1c030d35..392206e4d7 100644 --- a/openair2/X2AP/x2ap_eNB_encoder.c +++ b/openair2/X2AP/x2ap_eNB_encoder.c @@ -44,9 +44,9 @@ int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) DevAssert(buffer != NULL); DevAssert(len != NULL); - if (asn1_xer_print) { + //if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)pdu); - } + //} encoded = aper_encode_to_new_buffer(&asn_DEF_X2AP_X2AP_PDU, 0, pdu, (void **)buffer); diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 2a9406b632..ec3d3f4aa0 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -323,6 +323,10 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eN &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier); INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC); + X2AP_INFO("TAC: %d -> %02x%02x\n", instance_p->tac, + servedCellMember->servedCellInfo.tAC.buf[0], + servedCellMember->servedCellInfo.tAC.buf[1]); + plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); { MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); @@ -1341,7 +1345,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_request( ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { - X2AP_ERROR("Failed to encode X2 setup request\n"); + X2AP_ERROR("Failed to encode X2 setup response\n"); return -1; } @@ -1357,6 +1361,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_request( int x2ap_gNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) { + X2AP_INFO("In x2ap_gNB_generate_ENDC_x2_setup_response ()!\n"); X2AP_X2AP_PDU_t pdu; X2AP_ENDCX2SetupResponse_t *out; X2AP_ENDCX2SetupResponse_IEs_t *ie; @@ -1375,7 +1380,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( /* Prepare the X2AP message to encode */ memset(&pdu, 0, sizeof(pdu)); - pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_endcX2Setup; pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_ENDCX2SetupResponse; @@ -1394,6 +1399,12 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( INT32_TO_OCTET_STRING(instance_p->eNB_id, &ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID); + + X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id, + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[0], + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[1], + ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.buf[2]); + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, &ie_GNB_ENDC->value.choice.GlobalGNB_ID.pLMN_Identity); @@ -1414,6 +1425,12 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( &servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity); NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id, &servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier); + NR_EXTENDED_TAC_ID_TO_BIT_STRING(instance_p->tac, &servedCellMember->servedNRCellInfo.eXtended_TAC); + + X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac, + servedCellMember->servedNRCellInfo.eXtended_TAC.buf[0], + servedCellMember->servedNRCellInfo.eXtended_TAC.buf[1], + servedCellMember->servedNRCellInfo.eXtended_TAC.buf[2]); plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); { @@ -1421,9 +1438,9 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn); } - if (instance_p->frame_type[i] == TDD) { + if (instance_p->frame_type[i] == TDD) { // Panos: Remember to change that to TDD servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_ARFCN = instance_p->tdd_nRARFCN[i]; + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_ARFCN = 0; //instance_p->tdd_nRARFCN[i]; /*Missing addition of Frequency Band List item here, can't find it... */ switch (instance_p->N_RB_DL[i]) { case 50: @@ -1470,7 +1487,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( AssertFatal(0,"nr_X2Setupresponse not supported for FDD!"); } /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */ - INT16_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); + INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); } ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 55d09e45b5..1f577fa2a4 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1463,7 +1463,8 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance, DevAssert(instance_p != NULL); // Panos: Here we should be calling an ENDC specific setup response function - return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); + return x2ap_gNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); + //return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); } int diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index b4438b1aa5..cba8d0fd22 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -371,6 +371,26 @@ do { \ (bITsTRING)->bits_unused = 4; \ } while(0) +/* +#define INT16_TO_3_BYTE_BUFFER(x, buf) \ +do { \ + (buf)[0] = 0x00; \ + (buf)[1] = (x) >> 8; \ + (buf)[2] = (x); \ +} while(0) +*/ + +#define NR_EXTENDED_TAC_ID_TO_BIT_STRING(x, aSN) \ +do { \ + (aSN)->buf = calloc(3, sizeof(uint8_t)); \ + (aSN)->size = 3; \ + (aSN)->buf[0] = 0x00; \ + (aSN)->buf[1] = (x) >> 8; \ + (aSN)->buf[2] = (x); \ +} while(0) + + + /* TS 38.473 v15.2.1 section 9.3.1.55: * MaskedIMEISV is BIT_STRING(64) */ From 43a53f995219745bf793f0fa0fd185a431c59a45 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 23 Jul 2019 19:54:25 +0200 Subject: [PATCH 8/9] ENDC X2AP: Minor correction at x2ap decoder --- openair2/X2AP/x2ap_eNB_decoder.c | 8 ++++++-- openair2/X2AP/x2ap_eNB_handler.c | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index de9e773761..c7fc98763a 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -89,6 +89,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu) X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); break; + case X2AP_ProcedureCode_id_endcX2Setup: + X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); + break; + default: X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome.procedureCode); @@ -130,9 +134,9 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3 length, 0, 0); - if (asn1_xer_print) { + //if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu); - } + //} if (dec_ret.code != RC_OK) { X2AP_ERROR("Failed to decode pdu\n"); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 1f577fa2a4..cb2fee6d2d 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1581,6 +1581,16 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, for (int i=0; ivalue.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) { servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i]; x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI; + //servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0] + X2AP_INFO("TAC: %02x%02x%02x\n", + servedCellMember->servedNRCellInfo.eXtended_TAC.buf[0], + servedCellMember->servedNRCellInfo.eXtended_TAC.buf[1], + servedCellMember->servedNRCellInfo.eXtended_TAC.buf[2]); + + X2AP_INFO("PLMN: %02x%02x%02x\n", + servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0], + servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1], + servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]); } } } From 2955ae47313391c4733717afc9f2b8f75e1e8a9e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 1 Aug 2019 17:02:27 +0200 Subject: [PATCH 9/9] bugfix: compile with x2ap release 15.03 --- openair2/X2AP/x2ap_eNB_generate_messages.c | 13 ++++++++----- openair2/X2AP/x2ap_eNB_handler.c | 12 ++++++++---- openair3/UTILS/conversions.h | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index ec3d3f4aa0..be3002c197 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1425,12 +1425,15 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( &servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity); NR_CELL_ID_TO_BIT_STRING(instance_p->eNB_id, &servedCellMember->servedNRCellInfo.nrCellID.nRcellIdentifier); - NR_EXTENDED_TAC_ID_TO_BIT_STRING(instance_p->tac, &servedCellMember->servedNRCellInfo.eXtended_TAC); + servedCellMember->servedNRCellInfo.fiveGS_TAC = calloc(1, sizeof(X2AP_FiveGS_TAC_t)); + if (servedCellMember->servedNRCellInfo.fiveGS_TAC == NULL) + exit(1); + NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC); X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac, - servedCellMember->servedNRCellInfo.eXtended_TAC.buf[0], - servedCellMember->servedNRCellInfo.eXtended_TAC.buf[1], - servedCellMember->servedNRCellInfo.eXtended_TAC.buf[2]); + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); { @@ -1440,7 +1443,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_response( if (instance_p->frame_type[i] == TDD) { // Panos: Remember to change that to TDD servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_ARFCN = 0; //instance_p->tdd_nRARFCN[i]; + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i]; /*Missing addition of Frequency Band List item here, can't find it... */ switch (instance_p->N_RB_DL[i]) { case 50: diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index cb2fee6d2d..8e702a7e2e 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1582,10 +1582,14 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance, servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i]; x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI; //servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0] - X2AP_INFO("TAC: %02x%02x%02x\n", - servedCellMember->servedNRCellInfo.eXtended_TAC.buf[0], - servedCellMember->servedNRCellInfo.eXtended_TAC.buf[1], - servedCellMember->servedNRCellInfo.eXtended_TAC.buf[2]); + if (servedCellMember->servedNRCellInfo.fiveGS_TAC != NULL) { + X2AP_INFO("TAC: %02x%02x%02x\n", + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); + } else { + X2AP_INFO("TAC: (NULL)\n"); + } X2AP_INFO("PLMN: %02x%02x%02x\n", servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0], diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index cba8d0fd22..e39a841d96 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -380,7 +380,7 @@ do { \ } while(0) */ -#define NR_EXTENDED_TAC_ID_TO_BIT_STRING(x, aSN) \ +#define NR_FIVEGS_TAC_ID_TO_BIT_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(3, sizeof(uint8_t)); \ (aSN)->size = 3; \