merge develop

This commit is contained in:
laurent
2020-04-13 18:04:18 +02:00
242 changed files with 27021 additions and 18729 deletions
+97 -10
View File
@@ -101,7 +101,6 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_enb_data_p;
DevAssert(sctp_new_association_resp != NULL);
printf("x2ap_eNB_handle_sctp_association_resp at 1\n");
dump_trees();
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
@@ -129,7 +128,6 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
x2ap_enb_data_p = x2ap_get_eNB(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
DevAssert(x2ap_enb_data_p != NULL);
printf("x2ap_eNB_handle_sctp_association_resp at 2\n");
dump_trees();
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
@@ -142,17 +140,17 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
return;
}
printf("x2ap_eNB_handle_sctp_association_resp at 3\n");
dump_trees();
/* Update parameters */
x2ap_enb_data_p->assoc_id = sctp_new_association_resp->assoc_id;
x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
x2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
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);
if(instance_p->cell_type == CELL_MACRO_GNB)
x2ap_gNB_generate_ENDC_x2_setup_request(instance_p, x2ap_enb_data_p);
else
x2ap_eNB_generate_x2_setup_request(instance_p, x2ap_enb_data_p);
}
static
@@ -448,6 +446,78 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance,
x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack);
}
static
void x2ap_eNB_handle_sgNB_add_req(instance_t instance,
x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req)
{
x2ap_id_manager *id_manager;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
int ue_id;
/* TODO: remove hardcoded value */
x2ap_eNB_data = x2ap_is_eNB_id_in_list(3584);
DevAssert(x2ap_eNB_data != NULL);
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
/* allocate x2ap ID */
id_manager = &instance_p->id_manager;
ue_id = x2ap_allocate_new_id(id_manager);
if (ue_id == -1) {
X2AP_ERROR("could not allocate a new X2AP UE ID\n");
/* TODO: cancel NSA: send (to be defined) message to RRC */
exit(1);
}
/* id_source is ue_id, id_target is unknown yet */
x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1);
x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE);
x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id);
}
static
void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance,
x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_ENDC_sgnb_addition_req_ACK)
{
/* TODO: remove this hack (the goal is to find the correct
* eNodeB structure for the other end) - we need a proper way for RRC
* and X2AP to identify eNodeBs
* RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in
* the configuration file)
* as far as I understand.. CROUX
*/
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
/*int source_assoc_id = x2ap_ENDC_sgnb_addition_req_ACK->source_assoc_id;
int ue_id;
int id_source;
int id_target;*/
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
/*target = x2ap_get_eNB(NULL, source_assoc_id, 0);
DevAssert(target != NULL);*/
// rnti is a new information, save it
/*ue_id = x2ap_handover_req_ack->x2_id_target;
id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
id_target = ue_id;
x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);*/
//target = x2ap_get_eNB(NULL, 17, 0);
target = x2ap_is_eNB_id_in_list (3585); //Currently hardcoded. Need to extract it differently
DevAssert(target != NULL);
x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target, x2ap_ENDC_sgnb_addition_req_ACK, 0);
}
static
void x2ap_eNB_ue_context_release(instance_t instance,
x2ap_ue_context_release_t *x2ap_ue_context_release)
@@ -513,6 +583,17 @@ void *x2ap_task(void *arg) {
&X2AP_UE_CONTEXT_RELEASE(received_msg));
break;
case X2AP_ENDC_SGNB_ADDITION_REQ:
x2ap_eNB_handle_sgNB_add_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_ENDC_SGNB_ADDITION_REQ(received_msg));
break;
case X2AP_ENDC_SGNB_ADDITION_REQ_ACK:
x2ap_gNB_trigger_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(received_msg));
LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n");
break;
case SCTP_INIT_MSG_MULTI_CNF:
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
@@ -556,7 +637,6 @@ int is_x2ap_enabled(void)
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if (pthread_mutex_lock(&mutex)) goto mutex_error;
if (config_loaded) {
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
@@ -569,13 +649,20 @@ int is_x2ap_enabled(void)
/* TODO: do it per module - we check only first eNB */
config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]");
if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0)
enabled = 1;
if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0){
enabled = 1;
}
/*Consider also the case of enabling X2AP for a gNB by parsing a gNB configuration file*/
config_get(p, sizeof(p)/sizeof(paramdef_t), "gNBs.[0]");
if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0){
enabled = 1;
}
config_loaded = 1;
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
mutex_error:
+14 -4
View File
@@ -60,8 +60,14 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
break;
case X2AP_ProcedureCode_id_endcX2Setup:
X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
break;
X2AP_INFO("X2AP_ProcedureCode_id_endcX2Setup message!\n");
break;
case X2AP_ProcedureCode_id_sgNBAdditionPreparation:
X2AP_INFO("X2AP_ProcedureCode_id_sgNBAdditionPreparation message!\n");
break;
case X2AP_ProcedureCode_id_sgNBReconfigurationCompletion:
X2AP_INFO("X2AP_ProcedureCode_id_sgNBReconfigurationCompletion message!\n");
break;
default:
X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
@@ -93,6 +99,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_sgNBAdditionPreparation:
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);
@@ -134,9 +144,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");
+2 -2
View File
@@ -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);
+516 -185
View File
@@ -39,6 +39,7 @@
#include "x2ap_ids.h"
#include "x2ap_eNB_itti_messaging.h"
#include "X2AP_SupportedSULFreqBandItem.h"
#include "msc.h"
#include "assertions.h"
@@ -1097,7 +1098,6 @@ 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)
{
@@ -1118,8 +1118,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
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;
@@ -1128,7 +1126,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
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;
@@ -1144,7 +1141,6 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
/* 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;
@@ -1230,17 +1226,17 @@ int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p
return ret;
}
/*setup request message from an eNB to a gNB*/
int x2ap_eNB_generate_ENDC_x2_setup_request(
/*setup request message from a gNB to an eNB*/
int x2ap_gNB_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_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC;
X2AP_PLMN_Identity_t *plmn;
ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember;
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
X2AP_SupportedSULFreqBandItem_t *SULFreqBandItem;
uint8_t *buffer;
uint32_t len;
@@ -1262,24 +1258,166 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
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->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_en_gNB;
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t));
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqIEs_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.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC);
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_En_gNB_ENDCX2SetupReqIEs_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_ENDCX2SetupReqIEs__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) {
X2AP_FreqBandNrItem_t *freq_band;
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
/* addition of Frequency Band List */
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
if (freq_band == NULL)
exit(1);
freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */
SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t));
SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */
ASN_SEQUENCE_ADD(&freq_band->supportedSULBandList.list, SULFreqBandItem);
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
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;
}
}
else {
AssertFatal(0,"ENDC_X2Setuprequest 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.InitiatingNodeType_EndcX2Setup.choice.init_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 ENDC 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;
}
int x2ap_eNB_generate_ENDC_x2_setup_response(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
{
X2AP_X2AP_PDU_t pdu;
X2AP_ENDCX2SetupResponse_t *out;
X2AP_ENDCX2SetupResponse_IEs_t *ie;
X2AP_ENB_ENDCX2SetupReqAckIEs_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_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_eNB;
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqAckIEs_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.present = X2AP_ENB_ENDCX2SetupReqAckIEs__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);
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqIEs_t));
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t *)calloc(1, sizeof(X2AP_ENB_ENDCX2SetupReqAckIEs_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;
ie_ENB_ENDC->value.present = X2AP_ENB_ENDCX2SetupReqAckIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList;
{
for (int i = 0; i<instance_p->num_cc; i++){
@@ -1299,11 +1437,11 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
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;
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]) {
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;
@@ -1334,177 +1472,13 @@ int x2ap_eNB_generate_ENDC_x2_setup_request(
}
}
else {
AssertFatal(0,"X2Setuprequest not supported for TDD!");
AssertFatal(0,"X2Setupresponse 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 ENDC 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;
}
/*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
X2AP_FreqBandNrItem_t *freq_band;
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
/* addition of Frequency Band List */
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
if (freq_band == NULL)
exit(1);
freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
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(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
@@ -1521,3 +1495,360 @@ int x2ap_gNB_generate_ENDC_x2_setup_response(
return ret;
}
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBAdditionRequest_t *out;
X2AP_SgNBAdditionRequest_IEs_t *ie;
X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *e_RABS_ToBeAdded_SgNBAddReq_ItemIEs;
X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item_t *e_RABS_ToBeAdded_SgNBAddReq_Item;
uint8_t *buffer;
uint32_t len;
int ret = 0;
// Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted
// with values coming from RRC.
uint16_t nRencryptionAlgorithms = 0;
uint16_t nRintegrityProtectionAlgorithms = 0;
uint8_t SgNBSecurityKey[32] = { 0 };
int uEaggregateMaximumBitRateDownlink = 100000000;
int uEaggregateMaximumBitRateUplink = 100000000;
int e_rabs_tobeadded = 1;
int e_RAB_ID = 1;
int drb_ID = 2;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
long qCI = 1;
X2AP_Pre_emptionCapability_t pre_emptionCapability = X2AP_Pre_emptionCapability_shall_not_trigger_pre_emption;
X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability = X2AP_Pre_emptionVulnerability_not_pre_emptable;
priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY;
e_rab_tobe_added_t e_MCG_rabs_tobeadded;
e_MCG_rabs_tobeadded.gtp_teid = 0;
e_MCG_rabs_tobeadded.eNB_addr.length = 24;
uint8_t buf[20] = { 0 };
memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t));
FILE *fd;
fd = fopen("../../../executables/uecap.raw","r");
if (fd != NULL) {
OCTET_STRING_t CG_Config_Info;
CG_Config_Info.size = 4096;
CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t));
int msg_len=fread(CG_Config_Info.buf,1,CG_Config_Info.size,fd);
CG_Config_Info.size = msg_len;
/*char buffer[4096];
int msg_len=fread(buffer,1,4096,fd);*/
LOG_I(RRC,"Read in %d bytes for uecap\n",msg_len);
/*OCTET_STRING_t CG_Config_Info;
CG_Config_Info.size = 4096;
CG_Config_Info.buf = (uint8_t *)calloc(4096, sizeof(uint8_t));*/
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_sgNBAdditionPreparation;
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBAdditionRequest;
out = &pdu.choice.initiatingMessage.value.choice.SgNBAdditionRequest;
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; //Not sure about that
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_NRUESecurityCapabilities;
INT16_TO_BIT_STRING(nRencryptionAlgorithms, &ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
INT16_TO_BIT_STRING(nRintegrityProtectionAlgorithms, &ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNBSecurityKey;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_SgNBSecurityKey;
KENB_STAR_TO_BIT_STRING(SgNBSecurityKey, &ie->value.choice.SgNBSecurityKey);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_UEAggregateMaximumBitRate;
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
INT32_TO_BUFFER(uEaggregateMaximumBitRateDownlink, ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.buf);
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink.size = 4;
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf = (uint8_t *)calloc(4, sizeof(uint8_t));
INT32_TO_BUFFER(uEaggregateMaximumBitRateUplink, ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.buf);
ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink.size = 4;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
//Not sure if id should be X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List or X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList
ie->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_E_RABs_ToBeAdded_SgNBAddReqList;
for (int i=0;i<e_rabs_tobeadded;i++) {
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t));
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReq_Item;
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore;
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item;
e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item;
{
e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID;
e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item__resource_configuration_PR_sgNBPDCPpresent;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI = qCI;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = pre_emptionCapability;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority. pre_emptionVulnerability = pre_emptionVulnerability;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level;
//Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case
INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID);
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8;
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf =
calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_MCG_rabs_tobeadded.eNB_addr.buffer,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
}
}
ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list, e_RABS_ToBeAdded_SgNBAddReq_ItemIEs);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequest_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequest_IEs__value_PR_MeNBtoSgNBContainer;
ie->value.choice.MeNBtoSgNBContainer.buf = (uint8_t *)calloc(CG_Config_Info.size, sizeof(uint8_t));
memcpy(ie->value.choice.MeNBtoSgNBContainer.buf, CG_Config_Info.buf, CG_Config_Info.size);
ie->value.choice.MeNBtoSgNBContainer.size = CG_Config_Info.size; //4096;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\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);
fclose(fd);
}
else {
LOG_I(RRC, "uecap.raw file could not be opened... \n");
return -1;
}
return ret;
}
int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBAdditionRequestAcknowledge_t *out;
X2AP_SgNBAdditionRequestAcknowledge_IEs_t *ie;
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs;
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t *e_RABS_AdmittedToBeAdded_SgNBAddReq_Item;
uint8_t *buffer;
uint32_t len;
int ret = 0;
int MeNB_UE_X2AP_id = ue_id;
int SgNB_UE_X2AP_id = 0;
// Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted
// with values coming from RRC.
uint16_t nRencryptionAlgorithms = 0;
uint16_t nRintegrityProtectionAlgorithms = 0;
uint8_t SgNBSecurityKey[32] = { 0 };
int uEaggregateMaximumBitRateDownlink = 100000000;
int uEaggregateMaximumBitRateUplink = 100000000;
int e_rabs_admitted_tobeadded = 1;
int e_RAB_ID = 1;
long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present;
long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present;
long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present;
e_rab_setup_t e_SCG_rabs_tobeadded;
e_SCG_rabs_tobeadded.gtp_teid = 0;
e_SCG_rabs_tobeadded.eNB_addr.length = 24;
uint8_t buf[20] = { 0 };
memcpy(e_SCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t));
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_sgNBAdditionPreparation;
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBAdditionRequestAcknowledge;
out = &pdu.choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge;
// MeNB_UE_X2AP_id
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = MeNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// SgNB_UE_X2AP_id
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = SgNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList;
ie->criticality = X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList;
for (int i=0;i<e_rabs_admitted_tobeadded;i++) {
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t));
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore;
e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
{
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources;
if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent;
INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID);
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8;
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf =
calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_SCG_rabs_tobeadded.eNB_addr.buffer,
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
}
}
ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list, e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs);
}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNBtoMeNBContainer;
ie->value.choice.SgNBtoMeNBContainer.buf = (uint8_t *)calloc(x2ap_sgnb_addition_req_ACK->rrc_buffer_size, sizeof(uint8_t));
memcpy(ie->value.choice.SgNBtoMeNBContainer.buf, x2ap_sgnb_addition_req_ACK->rrc_buffer, x2ap_sgnb_addition_req_ACK->rrc_buffer_size);
ie->value.choice.SgNBtoMeNBContainer.size = x2ap_sgnb_addition_req_ACK->rrc_buffer_size; //4096;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\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;
}
int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id)
{
X2AP_X2AP_PDU_t pdu;
X2AP_SgNBReconfigurationComplete_t *out;
X2AP_SgNBReconfigurationComplete_IEs_t *ie;
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_sgNBReconfigurationCompletion;
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReconfigurationComplete;
out = &pdu.choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
ie->criticality= X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_UE_X2AP_ID;
ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_SgNB_UE_X2AP_ID;
ie->value.choice.SgNB_UE_X2AP_ID = SgNB_ue_id;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp;
ie->criticality = X2AP_Criticality_ignore;
ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_ResponseInformationSgNBReconfComp;
ie->value.choice.ResponseInformationSgNBReconfComp.present = X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp;
// meNBtoSgNBContainer should contain the RRCReconfigurationComplete message from the UE but in the specs 36.423(9.1.4.4) its presence is not mandatory
ie->value.choice.ResponseInformationSgNBReconfComp.choice.success_SgNBReconfComp.meNBtoSgNBContainer = NULL;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n");
return -1;
}
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
return ret;
}
+9 -2
View File
@@ -66,8 +66,15 @@ int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2
int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack);
int x2ap_eNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
int x2ap_gNB_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);
int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id);
int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id);
int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id);
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
+544 -157
View File
@@ -103,7 +103,7 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
int x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
int x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
@@ -114,8 +114,26 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
static
int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
/* Handlers matrix. Only eNB related procedure present here */
static
int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
static
int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
/* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */
x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */
{ x2ap_eNB_handle_handover_cancel, 0, 0 }, /* handoverCancel */
@@ -144,6 +162,8 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ 0, 0, 0 }, /* seNBinitiatedSeNBRelease */
{ 0, 0, 0 }, /* seNBCounterCheck */
{ 0, 0, 0 }, /* retrieveUEContext */
{ x2ap_gNB_handle_ENDC_sGNB_addition_request, x2ap_eNB_handle_ENDC_sGNB_addition_response, 0 }, /*X2AP_ProcedureCode_id_sgNBAdditionPreparation*/
{ x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBReconfigurationCompletion*/
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
@@ -151,9 +171,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ 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 },
{ x2ap_eNB_handle_ENDC_x2_setup_request, x2ap_gNB_handle_ENDC_x2_setup_response, 0 }, /*X2AP_ProcedureCode_id_endcX2Setup*/
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
@@ -1324,7 +1342,7 @@ int x2ap_eNB_handle_senb_addition_request_reject (instance_t instance,
}
int
x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu)
@@ -1332,12 +1350,12 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
X2AP_ENDCX2SetupRequest_t *x2_ENDC_SetupRequest;
X2AP_ENDCX2SetupRequest_IEs_t *ie;
X2AP_ENB_ENDCX2SetupReqIEs_t *ie_ENB_ENDC;
ServedEUTRAcellsENDCX2ManagementList__Member *servedCellMember;
X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC;
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
uint32_t gNB_id = 0;
x2ap_eNB_data = NULL;
DevAssert (pdu != NULL);
@@ -1372,156 +1390,11 @@ x2ap_gNB_handle_ENDC_x2_setup_request(instance_t instance,
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++) {
if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count > 0) {
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;
}
for (int i=0; i<ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) {
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];
ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i];
if (ie_GNB_ENDC == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
@@ -1606,6 +1479,146 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
}
}
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
return x2ap_eNB_generate_ENDC_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_ENB_ENDCX2SetupReqAckIEs_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_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
*/
// 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_eNB.list.count > 0) {
for (int i=0; i<ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list.count;i++) {
ie_ENB_ENDC = (X2AP_ENB_ENDCX2SetupReqAckIEs_t*) ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_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);
// 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;
}
}
/* Optionaly set the target eNB name */
/* The association is now ready as source and target eNBs know parameters of each other.
@@ -1622,4 +1635,378 @@ x2ap_gNB_handle_ENDC_x2_setup_response(instance_t instance,
return 0;
}
static
int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu)
{
X2AP_SgNBAdditionRequest_t *x2SgNBAdditionRequest;
X2AP_SgNBAdditionRequest_IEs_t *ie;
X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *e_RABS_ToBeAdded_SgNBAddReq_ItemIEs;
X2AP_E_RABs_ToBeAdded_SgNBAddReq_Item_t *e_RABS_ToBeAdded_SgNBAddReq_Item;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
MessageDef *msg;
int ue_id;
DevAssert (pdu != NULL);
x2SgNBAdditionRequest = &pdu->choice.initiatingMessage.value.choice.SgNBAdditionRequest;
/*if (stream == 0) {
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
// TODO: send a x2 failure response
return 0;
}*/
X2AP_DEBUG ("Received a new X2 SgNB Addition request\n");
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ);
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
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;
}
// 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");
// TODO: cancel handover: send HO preparation failure to source eNB
exit(1);
}
// rnti is unknown yet, must not be set to -1, 0 is fine
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);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_x2_id = ue_id;
/* X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_NRUESecurityCapabilities, true);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
/* X2AP_ProtocolIE_ID_id_SgNBSecurityKey */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_SgNBSecurityKey, true);
if ((ie->value.choice.SgNBSecurityKey.buf) &&
(ie->value.choice.SgNBSecurityKey.size == 32)) {
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ie->value.choice.SgNBSecurityKey.buf, 32);
} else {
X2AP_WARN ("Size of eNB key star does not match the expected value\n");
}
/* X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_SgNBUEAggregateMaximumBitRate, true);
//X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_ambr.br_dl =ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink;
//X2AP_ENDC_SGNB_ADDITION_REQ(msg).ue_ambr.br_ul = ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink;
/* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList, true);
if (ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count > 0) {
X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count;
for (int i=0;i<ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.count;i++) {
e_RABS_ToBeAdded_SgNBAddReq_ItemIEs = (X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs_t *) ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list.array[i];
e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].e_rab_id = e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID ;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].drb_ID = e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID;
if(e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.qci = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.qCI;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability;
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel;
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length =
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID,
X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid);
}
}
}
else {
X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n");
}
/* X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest,
X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true);
//X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
if (ie->value.choice.MeNBtoSgNBContainer.size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer, ie->value.choice.MeNBtoSgNBContainer.buf, ie->value.choice.MeNBtoSgNBContainer.size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = ie->value.choice.MeNBtoSgNBContainer.size;
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
return 0;
}
static
int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu)
{
X2AP_SgNBAdditionRequestAcknowledge_t *x2SgNBAdditionRequest_ack;
X2AP_SgNBAdditionRequestAcknowledge_IEs_t *ie;
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs;
X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item_t *e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
MessageDef *msg;
int ue_id;
int id_source;
int id_target;
int rnti;
DevAssert (pdu != NULL);
x2SgNBAdditionRequest_ack = &pdu->choice.successfulOutcome.value.choice.SgNBAdditionRequestAcknowledge;
/*if (stream == 0) {
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
// TODO: send a x2 failure response
return 0;
}*/
X2AP_DEBUG ("Received a new X2 SgNB Addition request\n");
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ_ACK);
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
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;
}
id_source = ie->value.choice.UE_X2AP_ID;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID;
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
}
id_target = ie->value.choice.SgNB_UE_X2AP_ID;
ue_id = id_source;
if (ue_id != x2ap_find_id_from_id_source(&instance_p->id_manager, id_source)) {
X2AP_WARN("incorrect/unknown X2AP IDs for UE (old ID %d new ID %d), ignoring sGNB addition response\n",
id_source, id_target);
itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return 0;
}
rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id);
/* id_target is a new information, store it */
x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target);
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rnti = rnti;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID;
/* X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReqList */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
}
if (ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count > 0) {
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count;
for (int i=0;i<ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.count;i++) {
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs_t *) ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list.array[i];
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item = &e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item;
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ;
if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer,
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length =
e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused;
OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID,
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid);
}
}
}
else {
X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n");
}
/* X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack,
X2AP_ProtocolIE_ID_id_SgNBtoMeNBContainer, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
}
//X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer;
if (ie->value.choice.SgNBtoMeNBContainer.size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, ie->value.choice.SgNBtoMeNBContainer.buf, ie->value.choice.SgNBtoMeNBContainer.size);
X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = ie->value.choice.SgNBtoMeNBContainer.size;
itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
return 0;
}
static
int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance,
uint32_t assoc_id,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu) {
X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete;
X2AP_SgNBReconfigurationComplete_IEs_t *ie;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
MessageDef *msg;
DevAssert (pdu != NULL);
x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete;
/*if (stream == 0) {
X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n");
// TODO: send a x2 failure response
return 0;
}*/
X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n");
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
X2AP_INFO("X2AP Association id: %d \n",assoc_id);
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
//Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead
msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE);
/* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
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;
}
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID;
/* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
}
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID;
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete,
X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
}
if(ie->value.choice.ResponseInformationSgNBReconfComp.present == X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_SUCCESS;
}
else {
X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_REJECT;
}
itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg);
return 0;
}
+2 -1
View File
@@ -37,7 +37,8 @@
typedef enum {
X2ID_STATE_SOURCE_PREPARE,
X2ID_STATE_SOURCE_OVERALL,
X2ID_STATE_TARGET
X2ID_STATE_TARGET,
X2ID_STATE_NSA_PREPARE,
} x2id_state_t;
typedef struct {