From 3dee153067b18d2a8bb8330b23baf53fbf8b8456 Mon Sep 17 00:00:00 2001 From: matzakos Date: Sun, 16 Jun 2019 20:17:59 +0200 Subject: [PATCH] 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,