merge develop
This commit is contained in:
+97
-10
@@ -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:
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user