Merge remote-tracking branch 'origin/dual-connectivity' into develop-nr-merge
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -85,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);
|
||||
@@ -126,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");
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -993,3 +997,519 @@ 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;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
/*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;
|
||||
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; i<instance_p->num_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 response\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;
|
||||
}
|
||||
|
||||
|
||||
/*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_INFO("In x2ap_gNB_generate_ENDC_x2_setup_response ()!\n");
|
||||
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_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;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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; i<instance_p->num_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);
|
||||
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.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));
|
||||
{
|
||||
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) { // Panos: Remember to change that to TDD
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
|
||||
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:
|
||||
//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 */
|
||||
INT8_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,4 +60,14 @@ 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 */);
|
||||
|
||||
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);
|
||||
|
||||
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_ */
|
||||
|
||||
@@ -84,6 +84,37 @@ 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_ack (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);
|
||||
|
||||
int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
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 */
|
||||
@@ -105,14 +136,27 @@ 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_ack, x2ap_eNB_handle_senb_addition_request_reject }, /* seNBAdditionPreparation */
|
||||
{ 0, 0, 0 }, /* seNBReconfigurationCompletion */
|
||||
{ 0, 0, 0 }, /* meNBinitiatedSeNBModificationPreparation */
|
||||
{ 0, 0, 0 }, /* seNBinitiatedSeNBModification */
|
||||
{ 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, x2ap_gNB_handle_ENDC_x2_setup_response, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
char *x2ap_direction2String(int x2ap_dir) {
|
||||
@@ -414,6 +458,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,
|
||||
@@ -1073,3 +1118,508 @@ 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)
|
||||
{
|
||||
|
||||
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;i<ie->value.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_ack (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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
x2ap_eNB_data = NULL;
|
||||
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; i<ie->value.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; i<ie_ENB_ENDC->value.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
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_gNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data);
|
||||
//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; i<ie->value.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; i<ie_GNB_ENDC->value.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]
|
||||
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],
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1],
|
||||
servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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_FIVEGS_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)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user