Commit ad60f97e authored by matzakos's avatar matzakos Committed by magounak

Dual connectivity: Basic implementation of...

Dual connectivity: Basic implementation of x2ap_eNB_handle_senb_addition_request and x2ap_eNB_generate_senb_addition_request_ack
parent a75f79d9
......@@ -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)
......@@ -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_ */
......@@ -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;i<x2ap_addition_req_ack->nb_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;i<x2ap_addition_req_ack->nb_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;
}
......@@ -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_ */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment