mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Replace duplicated KENB_STAR_TO_BIT_STRING and KGNB_STAR_TO_BIT_STRING macros with the unified AS_KEY_STAR_TO_BIT_STRING helper across X2AP, XNAP, M2AP, and M3AP code paths. Also switch allocation to calloc_or_fail for safer memory handling. No functional change intended. Signed-off-by: Rakesh BB <rakesh.bb@fsid-iisc.in>
2090 lines
104 KiB
C
2090 lines
104 KiB
C
/*
|
|
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
|
*/
|
|
|
|
/*!
|
|
* \brief x2ap procedures for eNB
|
|
*/
|
|
|
|
#include "intertask_interface.h"
|
|
|
|
#include "X2AP_LastVisitedCell-Item.h"
|
|
#include "X2AP_FreqBandNrItem.h"
|
|
|
|
#include "x2ap_common.h"
|
|
#include "x2ap_eNB.h"
|
|
#include "x2ap_eNB_generate_messages.h"
|
|
#include "x2ap_eNB_encoder.h"
|
|
#include "x2ap_eNB_decoder.h"
|
|
#include "x2ap_ids.h"
|
|
|
|
#include "x2ap_eNB_itti_messaging.h"
|
|
|
|
#include "assertions.h"
|
|
#include "conversions.h"
|
|
|
|
int x2ap_eNB_generate_x2_setup_request(
|
|
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_X2SetupRequest_t *out;
|
|
X2AP_X2SetupRequest_IEs_t *ie;
|
|
X2AP_PLMN_Identity_t *plmn;
|
|
ServedCells__Member *servedCellMember;
|
|
X2AP_GU_Group_ID_t *gu;
|
|
|
|
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_x2Setup;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_X2SetupRequest;
|
|
out = &pdu.choice.initiatingMessage.value.choice.X2SetupRequest;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_X2SetupRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_X2SetupRequest_IEs__value_PR_GlobalENB_ID;
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&ie->value.choice.GlobalENB_ID.pLMN_Identity);
|
|
ie->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->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
|
|
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
|
|
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
|
|
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
|
|
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_X2SetupRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_ServedCells;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_X2SetupRequest_IEs__value_PR_ServedCells;
|
|
{
|
|
for (int i = 0; i<instance_p->num_cc; i++){
|
|
servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
|
|
{
|
|
servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
|
|
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&servedCellMember->servedCellInfo.cellId.pLMN_Identity);
|
|
MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
|
|
&servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
|
|
|
|
INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
|
|
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
|
|
{
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
|
|
asn1cSeqAdd(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
|
|
}
|
|
|
|
if (instance_p->frame_type[i] == FDD) {
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
break;
|
|
case 15:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
break;
|
|
case 25:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
break;
|
|
case 50:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
break;
|
|
case 75:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
break;
|
|
case 100:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
|
|
switch (instance_p->subframeAssignment[i]) {
|
|
case 0:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
|
|
break;
|
|
case 1:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
|
|
break;
|
|
case 2:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
|
|
break;
|
|
case 3:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
|
|
break;
|
|
case 4:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
|
|
break;
|
|
case 5:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
|
|
break;
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
|
break;
|
|
}
|
|
switch (instance_p->specialSubframe[i]) {
|
|
case 0:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
|
|
break;
|
|
case 1:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
|
|
break;
|
|
case 2:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
|
|
break;
|
|
case 3:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
|
|
break;
|
|
case 4:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
|
|
break;
|
|
case 5:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
|
|
break;
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
|
|
break;
|
|
case 7:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
|
|
break;
|
|
case 8:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
|
break;
|
|
}
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
|
|
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
break;
|
|
case 15:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
break;
|
|
case 25:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
break;
|
|
case 50:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
break;
|
|
case 75:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
break;
|
|
case 100:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.ServedCells.list, servedCellMember);
|
|
}
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_X2SetupRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_GUGroupIDList;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_X2SetupRequest_IEs__value_PR_GUGroupIDList;
|
|
{
|
|
gu = (X2AP_GU_Group_ID_t *)calloc(1, sizeof(X2AP_GU_Group_ID_t));
|
|
{
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&gu->pLMN_Identity);
|
|
//@TODO: consider to update this value
|
|
INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.GUGroupIDList.list, gu);
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 setup request\n");
|
|
return -1;
|
|
}
|
|
|
|
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_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_X2SetupResponse_t *out;
|
|
X2AP_X2SetupResponse_IEs_t *ie;
|
|
X2AP_PLMN_Identity_t *plmn;
|
|
ServedCells__Member *servedCellMember;
|
|
X2AP_GU_Group_ID_t *gu;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
/* 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_x2Setup;
|
|
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_X2SetupResponse;
|
|
out = &pdu.choice.successfulOutcome.value.choice.X2SetupResponse;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_X2SetupResponse_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_GlobalENB_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_X2SetupResponse_IEs__value_PR_GlobalENB_ID;
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&ie->value.choice.GlobalENB_ID.pLMN_Identity);
|
|
ie->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->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
|
|
X2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
|
|
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
|
|
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
|
|
ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_X2SetupResponse_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_ServedCells;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_X2SetupResponse_IEs__value_PR_ServedCells;
|
|
{
|
|
for (int i = 0; i<instance_p->num_cc; i++){
|
|
servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
|
|
{
|
|
servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
|
|
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&servedCellMember->servedCellInfo.cellId.pLMN_Identity);
|
|
MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
|
|
&servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
|
|
|
|
INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
|
|
X2AP_INFO("TAC: %d -> %02x%02x\n", instance_p->tac,
|
|
servedCellMember->servedCellInfo.tAC.buf[0],
|
|
servedCellMember->servedCellInfo.tAC.buf[1]);
|
|
|
|
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
|
|
{
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
|
|
asn1cSeqAdd(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
|
|
}
|
|
|
|
if (instance_p->frame_type[i] == FDD) {
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
break;
|
|
case 15:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
break;
|
|
case 25:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
break;
|
|
case 50:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
break;
|
|
case 75:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
break;
|
|
case 100:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
|
|
switch (instance_p->subframeAssignment[i]) {
|
|
case 0:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
|
|
break;
|
|
case 1:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
|
|
break;
|
|
case 2:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
|
|
break;
|
|
case 3:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
|
|
break;
|
|
case 4:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
|
|
break;
|
|
case 5:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
|
|
break;
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
|
break;
|
|
}
|
|
switch (instance_p->specialSubframe[i]) {
|
|
case 0:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
|
|
break;
|
|
case 1:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
|
|
break;
|
|
case 2:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
|
|
break;
|
|
case 3:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
|
|
break;
|
|
case 4:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
|
|
break;
|
|
case 5:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
|
|
break;
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
|
|
break;
|
|
case 7:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
|
|
break;
|
|
case 8:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
|
break;
|
|
}
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
|
|
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 6:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
break;
|
|
case 15:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
break;
|
|
case 25:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
break;
|
|
case 50:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
break;
|
|
case 75:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
break;
|
|
case 100:
|
|
servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.ServedCells.list, servedCellMember);
|
|
}
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupResponse_IEs_t *)calloc(1, sizeof(X2AP_X2SetupResponse_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_GUGroupIDList;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_X2SetupResponse_IEs__value_PR_GUGroupIDList;
|
|
{
|
|
gu = (X2AP_GU_Group_ID_t *)calloc(1, sizeof(X2AP_GU_Group_ID_t));
|
|
{
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&gu->pLMN_Identity);
|
|
//@TODO: consider to update this value
|
|
INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.GUGroupIDList.list, gu);
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 setup response\n");
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_data_p->state = X2AP_ENB_STATE_READY;
|
|
|
|
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_x2_setup_failure(instance_t instance,
|
|
sctp_assoc_t assoc_id,
|
|
X2AP_Cause_PR cause_type,
|
|
long cause_value,
|
|
long time_to_wait)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_X2SetupFailure_t *out;
|
|
X2AP_X2SetupFailure_IEs_t *ie;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
/* Prepare the X2AP message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_unsuccessfulOutcome;
|
|
pdu.choice.unsuccessfulOutcome.procedureCode = X2AP_ProcedureCode_id_x2Setup;
|
|
pdu.choice.unsuccessfulOutcome.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.unsuccessfulOutcome.value.present = X2AP_UnsuccessfulOutcome__value_PR_X2SetupFailure;
|
|
out = &pdu.choice.unsuccessfulOutcome.value.choice.X2SetupFailure;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_X2SetupFailure_IEs_t *)calloc(1, sizeof(X2AP_X2SetupFailure_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_X2SetupFailure_IEs__value_PR_Cause;
|
|
|
|
x2ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* optional: consider to handle this later */
|
|
ie = (X2AP_X2SetupFailure_IEs_t *)calloc(1, sizeof(X2AP_X2SetupFailure_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_TimeToWait;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_X2SetupFailure_IEs__value_PR_TimeToWait;
|
|
|
|
if (time_to_wait > -1) {
|
|
ie->value.choice.TimeToWait = time_to_wait;
|
|
}
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 setup failure\n");
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p,
|
|
X2AP_Cause_PR cause_type,
|
|
long cause_value)
|
|
{
|
|
|
|
DevAssert (cause_p != NULL);
|
|
cause_p->present = cause_type;
|
|
|
|
switch (cause_type) {
|
|
case X2AP_Cause_PR_radioNetwork:
|
|
cause_p->choice.misc = cause_value;
|
|
break;
|
|
|
|
case X2AP_Cause_PR_transport:
|
|
cause_p->choice.misc = cause_value;
|
|
break;
|
|
|
|
case X2AP_Cause_PR_protocol:
|
|
cause_p->choice.misc = cause_value;
|
|
break;
|
|
|
|
case X2AP_Cause_PR_misc:
|
|
cause_p->choice.misc = cause_value;
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
x2ap_handover_req_t *x2ap_handover_req, int ue_id)
|
|
{
|
|
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_HandoverRequest_t *out;
|
|
X2AP_HandoverRequest_IEs_t *ie;
|
|
X2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
|
|
X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
|
|
X2AP_LastVisitedCell_Item_t *lastVisitedCell_Item;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
/* Prepare the X2AP handover message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_handoverPreparation;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_HandoverRequest;
|
|
out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_Cause;
|
|
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
|
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_TargetCell_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_ECGI;
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&ie->value.choice.ECGI.pLMN_Identity);
|
|
MACRO_ENB_ID_TO_CELL_IDENTITY(x2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_GUMMEI_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_GUMMEI;
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
|
|
//@TODO: consider to update these values
|
|
INT16_TO_OCTET_STRING(x2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
|
|
MME_CODE_TO_OCTET_STRING(x2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_UE_ContextInformation;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
|
|
//@TODO: consider to update this value
|
|
ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = x2ap_handover_req->mme_ue_s1ap_id;
|
|
|
|
AS_KEY_STAR_TO_BIT_STRING(x2ap_handover_req->kenb,
|
|
&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
|
|
|
|
if (x2ap_handover_req->kenb_ncc >=0) { // Check this condition
|
|
ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = x2ap_handover_req->kenb_ncc;
|
|
}
|
|
else {
|
|
ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
|
|
}
|
|
|
|
ENCRALG_TO_BIT_STRING(x2ap_handover_req->security_capabilities.encryption_algorithms,
|
|
&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
|
|
|
|
INTPROTALG_TO_BIT_STRING(x2ap_handover_req->security_capabilities.integrity_algorithms,
|
|
&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
|
|
|
|
//@TODO: update with proper UEAMPR
|
|
UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
|
|
UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
|
|
{
|
|
for (int i=0;i<x2ap_handover_req->nb_e_rabs_tobesetup;i++) {
|
|
e_RABS_ToBeSetup_ItemIEs = (X2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_ToBeSetup_ItemIEs_t));
|
|
e_RABS_ToBeSetup_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
|
|
e_RABS_ToBeSetup_ItemIEs->criticality = X2AP_Criticality_ignore;
|
|
e_RABS_ToBeSetup_ItemIEs->value.present = X2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
|
|
e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
|
|
{
|
|
e_RABs_ToBeSetup_Item->e_RAB_ID = x2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
|
|
e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = x2ap_handover_req->e_rab_param[i].qos.qci;
|
|
e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = x2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
|
|
e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = x2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
|
|
e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = x2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
|
|
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(x2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8);
|
|
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8;
|
|
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
|
|
calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
|
|
memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
|
x2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer,
|
|
e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
|
|
INT32_TO_OCTET_STRING(x2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
|
|
}
|
|
}
|
|
|
|
OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) x2ap_handover_req->rrc_buffer, x2ap_handover_req->rrc_buffer_size);
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_UE_HistoryInformation;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
|
|
//@TODO: consider to update this value
|
|
{
|
|
lastVisitedCell_Item = (X2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(X2AP_LastVisitedCell_Item_t));
|
|
lastVisitedCell_Item->present = X2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
|
|
MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
|
|
lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = X2AP_Cell_Size_small;
|
|
lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
|
|
asn1cSeqAdd(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
|
|
}
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 handover request\n");
|
|
abort();
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
x2ap_handover_req_ack_t *x2ap_handover_req_ack)
|
|
{
|
|
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_HandoverRequestAcknowledge_t *out;
|
|
X2AP_HandoverRequestAcknowledge_IEs_t *ie;
|
|
X2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs;
|
|
X2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item;
|
|
int ue_id;
|
|
int id_source;
|
|
int id_target;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
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;
|
|
|
|
/* Prepare the X2AP handover message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
|
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_handoverPreparation;
|
|
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
|
|
out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = id_source;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1;
|
|
ie->value.choice.UE_X2AP_ID_1 = id_target;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
|
|
|
|
{
|
|
for (int i=0;i<x2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
|
|
e_RABS_Admitted_ItemIEs = (X2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ItemIEs_t));
|
|
e_RABS_Admitted_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
|
|
e_RABS_Admitted_ItemIEs->criticality = X2AP_Criticality_ignore;
|
|
e_RABS_Admitted_ItemIEs->value.present = X2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
|
|
e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
|
|
{
|
|
e_RABs_Admitted_Item->e_RAB_ID = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
|
|
e_RABs_Admitted_Item->uL_GTP_TunnelEndpoint = NULL;
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint = (X2AP_GTPtunnelEndpoint_t *)calloc(1, sizeof(*e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint));
|
|
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size = (uint8_t)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length;
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.bits_unused = 0;
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf =
|
|
calloc(1, e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size);
|
|
|
|
memcpy (e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf,
|
|
x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer,
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size);
|
|
|
|
X2AP_DEBUG("X2 handover response target ip addr. length %lu bits_unused %d buf %d.%d.%d.%d\n",
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size,
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.bits_unused,
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[0],
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[1],
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[2],
|
|
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[3]);
|
|
|
|
INT32_TO_OCTET_STRING(x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid, &e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->gTP_TEID);
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
|
|
}
|
|
}
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer;
|
|
|
|
OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size);
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 handover response\n");
|
|
abort();
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release)
|
|
{
|
|
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_UEContextRelease_t *out;
|
|
X2AP_UEContextRelease_IEs_t *ie;
|
|
int ue_id;
|
|
int id_source;
|
|
int id_target;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti);
|
|
if (ue_id == -1) {
|
|
X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti);
|
|
exit(1);
|
|
}
|
|
id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
|
id_target = ue_id;
|
|
|
|
/* Prepare the X2AP ue context relase message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_uEContextRelease;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_UEContextRelease;
|
|
out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(X2AP_UEContextRelease_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = id_source;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(X2AP_UEContextRelease_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1;
|
|
ie->value.choice.UE_X2AP_ID_1 = id_target;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 UE Context Release\n");
|
|
abort();
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
int x2_ue_id,
|
|
x2ap_handover_cancel_cause_t cause)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_HandoverCancel_t *out;
|
|
X2AP_HandoverCancel_IEs_t *ie;
|
|
int ue_id;
|
|
int id_source;
|
|
int id_target;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
ue_id = x2_ue_id;
|
|
id_source = ue_id;
|
|
id_target = x2ap_id_get_id_target(&instance_p->id_manager, ue_id);
|
|
|
|
/* Prepare the X2AP handover cancel message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_handoverCancel;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_HandoverCancel;
|
|
out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(X2AP_HandoverCancel_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_HandoverCancel_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = id_source;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* optional */
|
|
if (id_target != -1) {
|
|
ie = (X2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(X2AP_HandoverCancel_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverCancel_IEs__value_PR_UE_X2AP_ID_1;
|
|
ie->value.choice.UE_X2AP_ID_1 = id_target;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
}
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(X2AP_HandoverCancel_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_HandoverCancel_IEs__value_PR_Cause;
|
|
switch (cause) {
|
|
case X2AP_T_RELOC_PREP_TIMEOUT:
|
|
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
|
ie->value.choice.Cause.choice.radioNetwork =
|
|
X2AP_CauseRadioNetwork_trelocprep_expiry;
|
|
break;
|
|
case X2AP_TX2_RELOC_OVERALL_TIMEOUT:
|
|
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
|
ie->value.choice.Cause.choice.radioNetwork =
|
|
X2AP_CauseRadioNetwork_tx2relocoverall_expiry;
|
|
break;
|
|
default:
|
|
/* we can't come here */
|
|
X2AP_ERROR("unhandled cancel cause\n");
|
|
exit(1);
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2 Handover Cancel\n");
|
|
abort();
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int x2ap_eNB_generate_senb_addition_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p
|
|
/* TODO: pass needed parameters */)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_SeNBAdditionRequest_t *out;
|
|
X2AP_SeNBAdditionRequest_IEs_t *ie;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
/* Prepare the X2AP SeNB Addition Request message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SeNBAdditionRequest;
|
|
out = &pdu.choice.initiatingMessage.value.choice.SeNBAdditionRequest;
|
|
|
|
/* id-MeNB-UE-X2AP-ID - mandatory - criticality reject */
|
|
ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = 0; /* TODO */
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* id-UE-SecurityCapabilities - conditional - criticality reject */
|
|
/* TODO */
|
|
|
|
/* id-SeNBSecurityKey - conditional - criticality reject */
|
|
/* TODO */
|
|
|
|
/* id-SeNBUEAggregateMaximumBitRate - mandatory - criticality reject */
|
|
ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate;
|
|
if (asn_imax2INTEGER(&ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink, 0) != 0) { /* TODO: right value */
|
|
LOG_E(X2AP, "%s:%d:%s: fatal asn1 error\n", __FILE__, __LINE__, __FUNCTION__);
|
|
exit(1);
|
|
}
|
|
if (asn_imax2INTEGER(&ie->value.choice.UEAggregateMaximumBitRate.uEaggregateMaximumBitRateUplink, 0) != 0) { /* TODO: right value */
|
|
LOG_E(X2AP, "%s:%d:%s: fatal asn1 error\n", __FILE__, __LINE__, __FUNCTION__);
|
|
exit(1);
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* id-ServingPLMN - optional - criticality ignore */
|
|
/* TODO */
|
|
|
|
/* id-E-RABs-ToBeAdded-List - mandatory - criticality reject */
|
|
ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SeNBUEAggregateMaximumBitRate;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_List;
|
|
/* TODO: set value of ie->value.choice.E_RABs_ToBeAdded_List.list */
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* id-MeNBtoSeNBContainer - mandatory - criticality reject */
|
|
ie = (X2AP_SeNBAdditionRequest_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_ProtocolIE_ID_id_MeNBtoSeNBContainer;
|
|
/* TODO: set value of ie->value.choice.MeNBtoSeNBContainer */
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* id-CSGMembershipStatus - optional - criticality reject */
|
|
/* TODO */
|
|
|
|
/* id-SeNB-UE-X2AP-ID - optional - criticality reject */
|
|
/* TODO */
|
|
|
|
/* id-SeNB-UE-X2AP-ID-Extension - optional - criticality reject */
|
|
/* TODO */
|
|
|
|
/* id-ExpectedUEBehaviour - optional - criticality ignore */
|
|
/* TODO */
|
|
|
|
/* id-MeNB-UE-X2AP-ID-Extension - optional - criticality reject */
|
|
/* TODO */
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode X2AP SeNB Addition Request\n");
|
|
abort();
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int x2ap_eNB_generate_senb_addition_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
x2ap_senb_addition_req_ack_t *x2ap_addition_req_ack)
|
|
{
|
|
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_SeNBAdditionRequestAcknowledge_t *out;
|
|
X2AP_SeNBAdditionRequestAcknowledge_IEs_t *ie;
|
|
X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *e_RABS_Admitted_ToBeAdded_ItemIEs;
|
|
X2AP_E_RABs_Admitted_ToBeAdded_Item_t *e_RABs_Admitted_ToBeAdded_Item;
|
|
//int ue_id;
|
|
//int ue_id_MeNB;
|
|
//int ue_id_SeNB;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
//ue_id = x2ap_addition_req_ack->x2_id_target; //Panos: change name to master_x2...
|
|
//id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
|
//id_target = ue_id;
|
|
|
|
/* Prepare the X2AP addition req. ack. message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
|
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_seNBAdditionPreparation;
|
|
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SeNBAdditionRequestAcknowledge;
|
|
out = &pdu.choice.successfulOutcome.value.choice.SeNBAdditionRequestAcknowledge;
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = 0;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SeNB_UE_X2AP_ID;
|
|
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;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_List;
|
|
ie->criticality = X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_ToBeAdded_List;
|
|
|
|
{
|
|
// SCG bearers to be added
|
|
for (int i=0;i<x2ap_addition_req_ack->nb_sCG_e_rabs_tobeadded;i++) {
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t));
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item;
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs->criticality = X2AP_Criticality_ignore;
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item;
|
|
e_RABs_Admitted_ToBeAdded_Item = &e_RABS_Admitted_ToBeAdded_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_Item;
|
|
{
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.e_RAB_ID = x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].e_rab_id;
|
|
INT32_TO_OCTET_STRING(x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].gtp_teid, &e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.gTP_TEID);
|
|
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.length/8);
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.length%8;
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf =
|
|
calloc(1,e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
|
|
memcpy (e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf,
|
|
x2ap_addition_req_ack->e_sCG_rabs_tobeadded[i].eNB_addr.buffer,
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.sCG_Bearer.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.E_RABs_Admitted_ToBeAdded_List.list, e_RABS_Admitted_ToBeAdded_ItemIEs);
|
|
}
|
|
|
|
// Split bearers to be added
|
|
for (int i=0;i<x2ap_addition_req_ack->nb_split_e_rabs_tobeadded;i++) {
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs = (X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs_t));
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_ToBeAdded_Item;
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs->criticality = X2AP_Criticality_ignore;
|
|
e_RABS_Admitted_ToBeAdded_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_Item;
|
|
e_RABs_Admitted_ToBeAdded_Item = &e_RABS_Admitted_ToBeAdded_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_Item;
|
|
{
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.e_RAB_ID = x2ap_addition_req_ack->e_split_rabs_tobeadded[i].e_rab_id;
|
|
INT32_TO_OCTET_STRING(x2ap_addition_req_ack->e_split_rabs_tobeadded[i].gtp_teid, &e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.gTP_TEID);
|
|
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.length/8);
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.length%8;
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.buf =
|
|
calloc(1,e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
|
|
memcpy (e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.buf,
|
|
x2ap_addition_req_ack->e_split_rabs_tobeadded[i].eNB_addr.buffer,
|
|
e_RABs_Admitted_ToBeAdded_Item->choice.split_Bearer.seNB_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.E_RABs_Admitted_ToBeAdded_List.list, e_RABS_Admitted_ToBeAdded_ItemIEs);
|
|
}
|
|
|
|
}
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
/* mandatory */
|
|
ie = (X2AP_SeNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SeNBAdditionRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SeNBtoMeNBContainer;
|
|
ie->criticality = X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_SeNBAdditionRequestAcknowledge_IEs__value_PR_SeNBtoMeNBContainer;
|
|
|
|
OCTET_STRING_fromBuf(&ie->value.choice.SeNBtoMeNBContainer, (char*) x2ap_addition_req_ack->rrc_buffer, x2ap_addition_req_ack->rrc_buffer_size);
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode SeNB addition response\n");
|
|
abort();
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*setup request message from 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)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_ENDCX2SetupRequest_t *out;
|
|
X2AP_ENDCX2SetupRequest_IEs_t *ie;
|
|
X2AP_En_gNB_ENDCX2SetupReqIEs_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_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_endcX2Setup;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_ENDCX2SetupRequest;
|
|
out = &pdu.choice.initiatingMessage.value.choice.ENDCX2SetupRequest;
|
|
|
|
ie = (X2AP_ENDCX2SetupRequest_IEs_t *)calloc(1, sizeof(X2AP_ENDCX2SetupRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup;
|
|
ie->value.present = X2AP_ENDCX2SetupRequest_IEs__value_PR_InitiatingNodeType_EndcX2Setup;
|
|
ie->value.choice.InitiatingNodeType_EndcX2Setup.present = X2AP_InitiatingNodeType_EndcX2Setup_PR_init_en_gNB;
|
|
|
|
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_ENDCX2SetupReqIEs__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);
|
|
|
|
asn1cSeqAdd(&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);
|
|
asn1cSeqAdd(&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 = 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 = instance_p->nr_band[i];
|
|
|
|
asn1cSeqAdd(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 24:
|
|
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb24;
|
|
break;
|
|
case 32:
|
|
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32;
|
|
break;
|
|
case 66:
|
|
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb66;
|
|
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;
|
|
case 217:
|
|
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb217;
|
|
break;
|
|
case 273:
|
|
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb273;
|
|
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);
|
|
}
|
|
asn1cSeqAdd(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember);
|
|
}
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC);
|
|
|
|
|
|
asn1cSeqAdd(&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;
|
|
}
|
|
|
|
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_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);
|
|
|
|
asn1cSeqAdd(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
|
|
|
|
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_ENDCX2SetupReqAckIEs__value_PR_ServedEUTRAcellsENDCX2ManagementList;
|
|
|
|
{
|
|
for (int i = 0; i<instance_p->num_cc; i++){
|
|
servedCellMember = (ServedEUTRAcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedEUTRAcellsENDCX2ManagementList__Member));
|
|
{
|
|
servedCellMember->servedEUTRACellInfo.pCI = instance_p->Nid_cell[i];
|
|
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
|
|
&servedCellMember->servedEUTRACellInfo.cellId.pLMN_Identity);
|
|
MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
|
|
&servedCellMember->servedEUTRACellInfo.cellId.eUTRANcellIdentifier);
|
|
|
|
INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedEUTRACellInfo.tAC);
|
|
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
|
|
{
|
|
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
|
|
asn1cSeqAdd(&servedCellMember->servedEUTRACellInfo.broadcastPLMNs.list, plmn);
|
|
}
|
|
|
|
if (instance_p->frame_type[i] == FDD) {
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 6:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
break;
|
|
case 15:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
break;
|
|
case 25:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
break;
|
|
case 50:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
break;
|
|
case 75:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
break;
|
|
case 100:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
|
|
|
|
switch (instance_p->subframeAssignment[i]) {
|
|
case 0:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
|
|
break;
|
|
case 1:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
|
|
break;
|
|
case 2:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
|
|
break;
|
|
case 3:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
|
|
break;
|
|
case 4:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
|
|
break;
|
|
case 5:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
|
|
break;
|
|
case 6:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
|
break;
|
|
}
|
|
switch (instance_p->specialSubframe[i]) {
|
|
case 0:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
|
|
break;
|
|
case 1:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
|
|
break;
|
|
case 2:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
|
|
break;
|
|
case 3:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
|
|
break;
|
|
case 4:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
|
|
break;
|
|
case 5:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
|
|
break;
|
|
case 6:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
|
|
break;
|
|
case 7:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
|
|
break;
|
|
case 8:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
|
break;
|
|
}
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
|
|
|
|
switch (instance_p->N_RB_DL[i]) {
|
|
case 6:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
|
break;
|
|
case 15:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
|
break;
|
|
case 25:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
|
break;
|
|
case 50:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
|
break;
|
|
case 75:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
|
break;
|
|
case 100:
|
|
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
|
break;
|
|
default:
|
|
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
asn1cSeqAdd(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
|
|
}
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
|
|
|
|
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode ENDC X2 setup response\n");
|
|
return -1;
|
|
}
|
|
|
|
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_addition_request(
|
|
x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req,
|
|
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;
|
|
uint16_t nRencryptionAlgorithms = x2ap_ENDC_sgnb_addition_req->security_capabilities.encryption_algorithms;
|
|
uint16_t nRintegrityProtectionAlgorithms = x2ap_ENDC_sgnb_addition_req->security_capabilities
|
|
.integrity_algorithms;
|
|
uint8_t SgNBSecurityKey[32] = { 0 };
|
|
int uEaggregateMaximumBitRateDownlink = x2ap_ENDC_sgnb_addition_req->ue_ambr.br_dl;
|
|
int uEaggregateMaximumBitRateUplink = x2ap_ENDC_sgnb_addition_req->ue_ambr.br_ul;
|
|
int e_rabs_tobeadded = x2ap_ENDC_sgnb_addition_req->nb_e_rabs_tobeadded;
|
|
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 = 0;
|
|
X2AP_Pre_emptionCapability_t pre_emptionCapability;
|
|
X2AP_Pre_emptionVulnerability_t pre_emptionVulnerability;
|
|
priority_level_t priority_level;
|
|
memcpy(SgNBSecurityKey, x2ap_ENDC_sgnb_addition_req->kgnb, sizeof(x2ap_ENDC_sgnb_addition_req->kgnb));
|
|
/*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);
|
|
asn1cSeqAdd(&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);
|
|
asn1cSeqAdd(&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;
|
|
AS_KEY_STAR_TO_BIT_STRING(SgNBSecurityKey, &ie->value.choice.SgNBSecurityKey);
|
|
asn1cSeqAdd(&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;
|
|
|
|
asn1cSeqAdd(&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_reject;
|
|
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 = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].drb_ID;
|
|
e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].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;
|
|
qCI = x2ap_ENDC_sgnb_addition_req->e_rab_param[i].qos.qci;
|
|
priority_level = x2ap_ENDC_sgnb_addition_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
|
|
pre_emptionCapability = x2ap_ENDC_sgnb_addition_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
|
|
pre_emptionVulnerability = x2ap_ENDC_sgnb_addition_req->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.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(x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].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 = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length/8;
|
|
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_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,
|
|
x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.buffer,
|
|
e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
}
|
|
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.E_RABs_ToBeAdded_SgNBAddReqList.list, e_RABS_ToBeAdded_SgNBAddReq_ItemIEs);
|
|
}
|
|
asn1cSeqAdd(&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;
|
|
if(NULL == (ie->value.choice.MeNBtoSgNBContainer.buf = (uint8_t *)
|
|
calloc(x2ap_ENDC_sgnb_addition_req->rrc_buffer_size, sizeof(uint8_t)))) {
|
|
X2AP_ERROR("Memory ALLocation failed\n");
|
|
exit(1);
|
|
}
|
|
memcpy(ie->value.choice.MeNBtoSgNBContainer.buf, x2ap_ENDC_sgnb_addition_req->rrc_buffer,
|
|
x2ap_ENDC_sgnb_addition_req->rrc_buffer_size);
|
|
ie->value.choice.MeNBtoSgNBContainer.size = x2ap_ENDC_sgnb_addition_req->rrc_buffer_size;
|
|
asn1cSeqAdd(&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;
|
|
}
|
|
# if 0 // TODO: Sanitizer complains we are trying to access this after free.
|
|
free(ie->value.choice.MeNBtoSgNBContainer.buf);
|
|
#endif
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
|
|
|
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 e_rabs_admitted_tobeadded = x2ap_sgnb_addition_req_ACK->nb_e_rabs_admitted_tobeadded;
|
|
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;
|
|
|
|
|
|
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 = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
|
asn1cSeqAdd(&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 = x2ap_id_get_id_target(&instance_p->id_manager, ue_id);
|
|
asn1cSeqAdd(&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 = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].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(x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].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 = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length/8;
|
|
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_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,
|
|
x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.buffer,
|
|
e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size);
|
|
}
|
|
|
|
}
|
|
asn1cSeqAdd(&ie->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAckList.list, e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs);
|
|
}
|
|
asn1cSeqAdd(&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;
|
|
asn1cSeqAdd(&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;
|
|
|
|
}
|
|
|
|
|
|
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 = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
|
|
asn1cSeqAdd(&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;
|
|
asn1cSeqAdd(&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;
|
|
asn1cSeqAdd(&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;
|
|
|
|
}
|
|
|
|
int x2ap_eNB_generate_ENDC_x2_SgNB_release_request(
|
|
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
int x2_id_source, int x2_id_target, x2ap_cause_t cause)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_SgNBReleaseRequest_t *out;
|
|
X2AP_SgNBReleaseRequest_IEs_t *ie;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequest;
|
|
out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequest;
|
|
|
|
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = x2_id_source;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2_id_target != -1) {
|
|
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_SgNB_UE_X2AP_ID;
|
|
ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
}
|
|
|
|
ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
|
ie->criticality= X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_Cause;
|
|
switch (cause) {
|
|
case X2AP_CAUSE_T_DC_PREP_TIMEOUT:
|
|
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
|
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCprep_expiry;
|
|
break;
|
|
case X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST:
|
|
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
|
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_radio_connection_with_UE_lost;
|
|
break;
|
|
default:
|
|
X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause);
|
|
exit(1);
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_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;
|
|
}
|
|
|
|
int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(
|
|
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_SgNBReleaseRequestAcknowledge_t *out;
|
|
X2AP_SgNBReleaseRequestAcknowledge_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;
|
|
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
|
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease;
|
|
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_ignore;
|
|
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseRequestAcknowledge;
|
|
out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseRequestAcknowledge;
|
|
|
|
ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID;
|
|
ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n");
|
|
return -1;
|
|
}
|
|
|
|
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_release_required(
|
|
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
int x2_id_source, int x2_id_target, x2ap_cause_t cause)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_SgNBReleaseRequired_t *out;
|
|
X2AP_SgNBReleaseRequired_IEs_t *ie;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
/* Prepare the X2AP message to encode */
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage;
|
|
pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease;
|
|
pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequired;
|
|
out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequired;
|
|
|
|
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = x2_id_source;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_reject;
|
|
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_SgNB_UE_X2AP_ID;
|
|
ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_Cause;
|
|
ie->criticality= X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_Cause;
|
|
switch (cause) {
|
|
case X2AP_CAUSE_T_DC_OVERALL_TIMEOUT:
|
|
ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork;
|
|
ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCoverall_expiry;
|
|
break;
|
|
default:
|
|
X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause);
|
|
exit(1);
|
|
}
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_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;
|
|
}
|
|
|
|
int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(
|
|
x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
|
|
int menb_ue_x2ap_id, int sgnb_ue_x2ap_id)
|
|
{
|
|
X2AP_X2AP_PDU_t pdu;
|
|
X2AP_SgNBReleaseConfirm_t *out;
|
|
X2AP_SgNBReleaseConfirm_IEs_t *ie;
|
|
|
|
uint8_t *buffer;
|
|
uint32_t len;
|
|
int ret = 0;
|
|
|
|
DevAssert(instance_p != NULL);
|
|
DevAssert(x2ap_eNB_data_p != NULL);
|
|
|
|
memset(&pdu, 0, sizeof(pdu));
|
|
pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome;
|
|
pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease;
|
|
pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject;
|
|
pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseConfirm;
|
|
out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseConfirm;
|
|
|
|
ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_UE_X2AP_ID;
|
|
ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t));
|
|
ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID;
|
|
ie->criticality= X2AP_Criticality_ignore;
|
|
ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_SgNB_UE_X2AP_ID;
|
|
ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id;
|
|
asn1cSeqAdd(&out->protocolIEs.list, ie);
|
|
|
|
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
|
X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n");
|
|
return -1;
|
|
}
|
|
|
|
x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0);
|
|
|
|
return ret;
|
|
}
|