Merge remote-tracking branch 'origin/x2ho_tdd' into develop_integration_2019_w30
This commit is contained in:
@@ -25,4 +25,8 @@ MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_del
|
||||
MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_enb_delete_tunnel_resp_t, Gtpv1uDeleteTunnelResp)
|
||||
MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_ind_t, Gtpv1uTunnelDataInd)
|
||||
MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_req_t, Gtpv1uTunnelDataReq)
|
||||
MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_req_t,Gtpv1uDataForwardingReq)
|
||||
MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_ind_t,Gtpv1uDataForwardingInd)
|
||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq)
|
||||
MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
|
||||
MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req)
|
||||
|
||||
@@ -33,10 +33,33 @@
|
||||
#define GTPV1U_ENB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDeleteTunnelResp
|
||||
#define GTPV1U_ENB_TUNNEL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataInd
|
||||
#define GTPV1U_ENB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataReq
|
||||
#define GTPV1U_ENB_DATA_FORWARDING_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDataForwardingReq
|
||||
#define GTPV1U_ENB_DATA_FORWARDING_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDataForwardingInd
|
||||
#define GTPV1U_ENB_END_MARKER_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerReq
|
||||
#define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd
|
||||
|
||||
#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req
|
||||
|
||||
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
|
||||
|
||||
typedef struct gtpv1u_enb_create_x2u_tunnel_req_s {
|
||||
rnti_t rnti;
|
||||
int num_tunnels;
|
||||
teid_t tenb_X2u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t enb_addr[GTPV1U_MAX_BEARERS_PER_UE];
|
||||
} gtpv1u_enb_create_x2u_tunnel_req_t;
|
||||
|
||||
typedef struct gtpv1u_enb_create_x2u_tunnel_resp_s {
|
||||
uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
|
||||
rnti_t rnti;
|
||||
int num_tunnels;
|
||||
teid_t enb_X2u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
|
||||
ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
|
||||
transport_layer_addr_t enb_addr;
|
||||
} gtpv1u_enb_create_x2u_tunnel_resp_t;
|
||||
|
||||
|
||||
typedef struct gtpv1u_enb_create_tunnel_req_s {
|
||||
rnti_t rnti;
|
||||
int num_tunnels;
|
||||
@@ -99,6 +122,50 @@ typedef struct gtpv1u_enb_tunnel_data_req_s {
|
||||
rb_id_t rab_id;
|
||||
} gtpv1u_enb_tunnel_data_req_t;
|
||||
|
||||
typedef struct gtpv1u_enb_data_forwarding_req_s {
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
uint32_t offset; ///< start of message offset in buffer
|
||||
rnti_t rnti;
|
||||
rb_id_t rab_id;
|
||||
} gtpv1u_enb_data_forwarding_req_t;
|
||||
|
||||
typedef struct gtpv1u_enb_data_forwarding_ind_s {
|
||||
uint32_t frame;
|
||||
uint8_t enb_flag;
|
||||
uint32_t rb_id;
|
||||
uint32_t muip;
|
||||
uint32_t confirmp;
|
||||
uint32_t sdu_size;
|
||||
uint8_t *sdu_p;
|
||||
uint8_t mode;
|
||||
uint16_t rnti;
|
||||
uint8_t module_id;
|
||||
uint8_t eNB_index;
|
||||
} gtpv1u_enb_data_forwarding_ind_t;
|
||||
|
||||
typedef struct gtpv1u_enb_end_marker_req_s {
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
uint32_t offset; ///< start of message offset in buffer
|
||||
rnti_t rnti;
|
||||
rb_id_t rab_id;
|
||||
} gtpv1u_enb_end_marker_req_t;
|
||||
|
||||
typedef struct gtpv1u_enb_end_marker_ind_s {
|
||||
uint32_t frame;
|
||||
uint8_t enb_flag;
|
||||
uint32_t rb_id;
|
||||
uint32_t muip;
|
||||
uint32_t confirmp;
|
||||
uint32_t sdu_size;
|
||||
uint8_t *sdu_p;
|
||||
uint8_t mode;
|
||||
uint16_t rnti;
|
||||
uint8_t module_id;
|
||||
uint8_t eNB_index;
|
||||
} gtpv1u_enb_end_marker_ind_t;
|
||||
|
||||
typedef struct {
|
||||
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
|
||||
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
|
||||
|
||||
@@ -107,6 +107,8 @@ typedef struct x2ap_register_enb_req_s {
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
uint32_t subframeAssignment[MAX_NUM_CCs];
|
||||
uint32_t specialSubframe[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
|
||||
/* To be considered for TDD */
|
||||
|
||||
@@ -2509,6 +2509,8 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
|
||||
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = ccparams_lte.tdd_config;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s;
|
||||
} else {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
|
||||
|
||||
@@ -113,22 +113,22 @@ static const eutra_bandentry_t eutra_bandtable[] = {
|
||||
{30, 23050, 23250, 23500, 23600, 97700},
|
||||
{31, 45250, 34900, 46250, 35900, 98700},
|
||||
{32, 0, 0, 14520, 14960, 99200},
|
||||
{33, 19000, 19200, 19000, 19200, 36000},
|
||||
{34, 20100, 20250, 20100, 20250, 36200},
|
||||
{35, 18500, 19100, 18500, 19100, 36350},
|
||||
{36, 19300, 19900, 19300, 19900, 36950},
|
||||
{37, 19100, 19300, 19100, 19300, 37550},
|
||||
{38, 25700, 26200, 25700, 26300, 37750},
|
||||
{39, 18800, 19200, 18800, 19200, 38250},
|
||||
{40, 23000, 24000, 23000, 24000, 38650},
|
||||
{41, 24960, 26900, 24960, 26900, 39650},
|
||||
{42, 34000, 36000, 34000, 36000, 41590},
|
||||
{43, 36000, 38000, 36000, 38000, 43590},
|
||||
{44, 7030, 8030, 7030, 8030, 45590},
|
||||
{45, 14470, 14670, 14470, 14670, 46590},
|
||||
{46, 51500, 59250, 51500, 59250, 46790},
|
||||
{65, 19200, 20100, 21100, 22000, 65536},
|
||||
{66, 17100, 18000, 21100, 22000, 66436},
|
||||
{33, 19000, 19200, 19000, 19200, 360000},
|
||||
{34, 20100, 20250, 20100, 20250, 362000},
|
||||
{35, 18500, 19100, 18500, 19100, 363500},
|
||||
{36, 19300, 19900, 19300, 19900, 369500},
|
||||
{37, 19100, 19300, 19100, 19300, 375500},
|
||||
{38, 25700, 26200, 25700, 26300, 377500},
|
||||
{39, 18800, 19200, 18800, 19200, 382500},
|
||||
{40, 23000, 24000, 23000, 24000, 386500},
|
||||
{41, 24960, 26900, 24960, 26900, 396500},
|
||||
{42, 34000, 36000, 34000, 36000, 415900},
|
||||
{43, 36000, 38000, 36000, 38000, 435900},
|
||||
{44, 7030, 8030, 7030, 8030, 455900},
|
||||
{45, 14470, 14670, 14470, 14670, 465900},
|
||||
{46, 51500, 59250, 51500, 59250, 467900},
|
||||
{65, 19200, 20100, 21100, 22000, 655360},
|
||||
{66, 17100, 18000, 21100, 22000, 664360},
|
||||
{67, 0, 0, 7380, 7580, 67336},
|
||||
{68, 6980, 7280, 7530, 7830, 67536}
|
||||
};
|
||||
|
||||
@@ -348,11 +348,24 @@ typedef enum HO_STATE_e {
|
||||
HO_COMPLETE, // initiated by the target eNB
|
||||
HO_REQUEST,
|
||||
HO_ACK,
|
||||
HO_FORWARDING,
|
||||
HO_CONFIGURED,
|
||||
HO_END_MARKER,
|
||||
HO_FORWARDING_COMPLETE,
|
||||
HO_RELEASE,
|
||||
HO_CANCEL
|
||||
} HO_STATE_t;
|
||||
|
||||
typedef enum DATA_FORWARDING_STATE_e {
|
||||
FORWARDING_EMPTY=0,
|
||||
FORWARDING_NO_EMPTY
|
||||
} DATA_FORWARDING_STATE_t;
|
||||
|
||||
typedef enum DATA_ENDMARK_STATE_e {
|
||||
ENDMARK_EMPTY=0,
|
||||
ENDMARK_NO_EMPTY
|
||||
} DATA_ENDMARK_STATE_t;
|
||||
|
||||
typedef enum SL_TRIGGER_e {
|
||||
SL_RECEIVE_COMMUNICATION=0,
|
||||
SL_TRANSMIT_RELAY_ONE_TO_ONE,
|
||||
@@ -477,6 +490,9 @@ typedef struct HANDOVER_INFO_s {
|
||||
uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */
|
||||
int size; /* size of above message in bytes */
|
||||
int x2_id; /* X2AP UE ID in the target eNB */
|
||||
uint32_t x2u_teid;
|
||||
DATA_FORWARDING_STATE_t forwarding_state;
|
||||
DATA_ENDMARK_STATE_t endmark_state;
|
||||
} HANDOVER_INFO;
|
||||
|
||||
typedef struct PER_EVENT_s {
|
||||
@@ -693,6 +709,12 @@ typedef struct eNB_RRC_UE_s {
|
||||
uint32_t enb_gtp_teid[S1AP_MAX_E_RAB];
|
||||
transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB];
|
||||
rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB];
|
||||
/* Total number of e_rab already setup in the list */
|
||||
uint8_t nb_x2u_e_rabs;
|
||||
// LG: For GTPV1 TUNNELS(X2U)
|
||||
uint32_t enb_gtp_x2u_teid[S1AP_MAX_E_RAB];
|
||||
transport_layer_addr_t enb_gtp_x2u_addrs[S1AP_MAX_E_RAB];
|
||||
rb_id_t enb_gtp_x2u_ebi[S1AP_MAX_E_RAB];
|
||||
uint32_t ul_failure_timer;
|
||||
uint32_t ue_release_timer;
|
||||
uint32_t ue_release_timer_thres;
|
||||
|
||||
+238
-6
@@ -4060,8 +4060,40 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt
|
||||
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t));
|
||||
*(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq; // Default is 15 or 0dB
|
||||
//<<<<<<< HEAD
|
||||
MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB
|
||||
if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) {
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1 = CALLOC(1, sizeof(struct LTE_MeasObjectEUTRA__ext1));
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measCycleSCell_r10 = NULL;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10 = CALLOC(1, sizeof(struct LTE_MeasSubframePatternConfigNeigh_r10));
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->present=LTE_MeasSubframePatternConfigNeigh_r10_PR_setup;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.present=LTE_MeasSubframePattern_r10_PR_subframePatternTDD_r10;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.present=LTE_MeasSubframePattern_r10__subframePatternTDD_r10_PR_subframeConfig1_5_r10;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf=CALLOC(3, sizeof(uint8_t));
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.size=3;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.bits_unused=4;
|
||||
switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) {
|
||||
case 1: //subframe 0,4,5,9
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x8C;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x63;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x10;
|
||||
break;
|
||||
|
||||
default: //subframe 0 , 5
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x84;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x21;
|
||||
MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
|
||||
(LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
|
||||
CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
|
||||
//=======
|
||||
// MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t));
|
||||
// *(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq; // Default is 15 or 0dB
|
||||
//>>>>>>> origin/OAI_develop
|
||||
|
||||
if (RC.rrc[ctxt_pP->module_id]->num_neigh_cells > 0) {
|
||||
MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
|
||||
@@ -4557,7 +4589,9 @@ rrc_eNB_process_MeasurementReport(
|
||||
/* HO info struct may not be needed anymore */
|
||||
ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
|
||||
ue_context_pP->ue_context.Status = RRC_HO_EXECUTION;
|
||||
|
||||
ue_context_pP->ue_context.handover_info->state = HO_REQUEST;
|
||||
|
||||
/* HO Preparation message */
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ);
|
||||
rrc_eNB_generate_HandoverPreparationInformation(
|
||||
@@ -4685,8 +4719,8 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
|
||||
RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p);
|
||||
LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid);
|
||||
ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info)));
|
||||
ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
|
||||
ue_context_target_p->ue_context.handover_info->state = HO_ACK;
|
||||
//ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
|
||||
//ue_context_target_p->ue_context.handover_info->state = HO_ACK;
|
||||
ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id;
|
||||
ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id;
|
||||
memset (ue_context_target_p->ue_context.nh, 0, 32);
|
||||
@@ -4760,6 +4794,10 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
|
||||
ue_context_target_p->ue_context.e_rab[i].param.e_rab_id,
|
||||
ue_context_target_p->ue_context.e_rab[i].param.gtp_teid);
|
||||
}
|
||||
rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(mod_id, ue_context_target_p);
|
||||
|
||||
ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
|
||||
ue_context_target_p->ue_context.handover_info->state = HO_ACK;
|
||||
}
|
||||
|
||||
void rrc_eNB_process_handoverCommand(
|
||||
@@ -4975,7 +5013,8 @@ check_handovers(
|
||||
if (ue_context_p->ue_context.handover_info->state == HO_ACK) {
|
||||
MessageDef *msg;
|
||||
// Configure target
|
||||
ue_context_p->ue_context.handover_info->state = HO_CONFIGURED;
|
||||
ue_context_p->ue_context.handover_info->state = HO_FORWARDING;
|
||||
|
||||
msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ_ACK);
|
||||
rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer,
|
||||
&X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size);
|
||||
@@ -4988,13 +5027,162 @@ check_handovers(
|
||||
X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs;
|
||||
|
||||
for (int i=0; i<ue_context_p->ue_context.setup_e_rabs; i++) {
|
||||
/* set gtpv teid info */
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_p->ue_context.enb_gtp_x2u_teid[i];
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_p->ue_context.enb_gtp_x2u_addrs[i];
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
|
||||
LOG_I(RRC, "RRC Sends X2 HO ACK to the source eNB at frame %d and subframe %d \n", ctxt_pP->frame,ctxt_pP->subframe);
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.Status == RRC_RECONFIGURED
|
||||
&& ue_context_p->ue_context.handover_info != NULL &&
|
||||
ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) {
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
MessageDef *msg_p;
|
||||
int result;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
do {
|
||||
// Checks if a message has been sent to PDCP sub-task
|
||||
itti_poll_msg (TASK_DATA_FORWARDING, &msg_p);
|
||||
|
||||
if (msg_p != NULL) {
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case GTPV1U_ENB_DATA_FORWARDING_IND:
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(
|
||||
&ctxt,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).module_id,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).enb_flag,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rnti,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).frame,
|
||||
0,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).eNB_index);
|
||||
LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
|
||||
PROTOCOL_CTXT_ARGS(&ctxt),
|
||||
ITTI_MSG_NAME (msg_p),
|
||||
ITTI_MSG_ORIGIN_NAME(msg_p),
|
||||
ITTI_MSG_INSTANCE (msg_p),
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode);
|
||||
|
||||
LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
|
||||
result = pdcp_data_req (&ctxt,
|
||||
SRB_FLAG_NO,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_size,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
, NULL, NULL
|
||||
#endif
|
||||
);
|
||||
if (result != TRUE){
|
||||
LOG_E(RRC, "target enb send data forwarding buffer to PDCP request failed!\n");
|
||||
}else{
|
||||
LOG_D(RRC, "target enb send data forwarding buffer to PDCP!\n");
|
||||
}
|
||||
|
||||
// Message buffer has been processed, free it now.
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
} while(msg_p != NULL);
|
||||
ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_EMPTY;
|
||||
}
|
||||
if( ue_context_p->ue_context.Status == RRC_RECONFIGURED &&
|
||||
ue_context_p->ue_context.handover_info != NULL &&
|
||||
ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_EMPTY &&
|
||||
ue_context_p->ue_context.handover_info->endmark_state == ENDMARK_NO_EMPTY &&
|
||||
ue_context_p->ue_context.handover_info->state == HO_END_MARKER ){
|
||||
|
||||
MessageDef *msg_p;
|
||||
int result;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
do {
|
||||
// Checks if a message has been sent to PDCP sub-task
|
||||
itti_poll_msg (TASK_END_MARKER, &msg_p);
|
||||
|
||||
if (msg_p != NULL) {
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case GTPV1U_ENB_END_MARKER_IND:
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(
|
||||
&ctxt,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).module_id,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).enb_flag,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).rnti,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).frame,
|
||||
0,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).eNB_index);
|
||||
LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
|
||||
PROTOCOL_CTXT_ARGS(&ctxt),
|
||||
ITTI_MSG_NAME (msg_p),
|
||||
ITTI_MSG_ORIGIN_NAME(msg_p),
|
||||
ITTI_MSG_INSTANCE (msg_p),
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode);
|
||||
|
||||
LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
|
||||
result = pdcp_data_req (&ctxt,
|
||||
SRB_FLAG_NO,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).rb_id,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).muip,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).confirmp,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_size,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p,
|
||||
GTPV1U_ENB_END_MARKER_IND (msg_p).mode
|
||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||
, NULL, NULL
|
||||
#endif
|
||||
);
|
||||
if (result != TRUE){
|
||||
LOG_E(RRC, "target enb send spgw buffer to PDCP request failed!\n");
|
||||
}else{
|
||||
LOG_D(RRC, "target enb send spgw buffer to PDCP!\n");
|
||||
}
|
||||
|
||||
// Message buffer has been processed, free it now.
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(RRC, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
} while(msg_p != NULL);
|
||||
|
||||
ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_EMPTY;
|
||||
ue_context_p->ue_context.handover_info->state = HO_FORWARDING_COMPLETE;
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7557,6 +7745,9 @@ rrc_eNB_decode_dcch(
|
||||
dedicated_DRB = 3;
|
||||
RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
|
||||
ue_context_p->ue_context.Status = RRC_RECONFIGURED;
|
||||
if(ue_context_p->ue_context.handover_info){
|
||||
ue_context_p->ue_context.handover_info->state = HO_CONFIGURED;
|
||||
}
|
||||
LOG_I(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
|
||||
@@ -7635,6 +7826,7 @@ rrc_eNB_decode_dcch(
|
||||
}
|
||||
} else if(dedicated_DRB == 0) {
|
||||
if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1) {
|
||||
|
||||
rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
|
||||
ue_context_p);
|
||||
} else {
|
||||
@@ -8540,7 +8732,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
instance = ITTI_MSG_INSTANCE(msg_p);
|
||||
/* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */
|
||||
if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS)
|
||||
LOG_I(RRC,"Received message %s\n",msg_name_p);
|
||||
LOG_D(RRC,"Received message %s\n",msg_name_p);
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
@@ -8679,6 +8871,9 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
|
||||
case X2AP_HANDOVER_REQ_ACK: {
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
x2ap_handover_req_ack_t *x2ap_handover_req_ack = NULL;
|
||||
hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
|
||||
gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
|
||||
if (ue_context_p == NULL) {
|
||||
/* is it possible? */
|
||||
@@ -8690,7 +8885,44 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
DevAssert(ue_context_p != NULL);
|
||||
|
||||
if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort();
|
||||
|
||||
hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, ue_context_p->ue_context.rnti, (void**)>pv1u_ue_data_p);
|
||||
/* set target enb gtp teid */
|
||||
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
||||
LOG_E(RRC, "X2AP_HANDOVER_REQ_ACK func(), hashtable_get failed: while getting ue rnti %x in hashtable ue_mapping\n", ue_context_p->ue_context.rnti);
|
||||
} else {
|
||||
uint8_t nb_e_rabs_tobesetup = 0;
|
||||
ebi_t eps_bearer_id = 0;
|
||||
int ip_offset = 0;
|
||||
in_addr_t in_addr;
|
||||
x2ap_handover_req_ack = &X2AP_HANDOVER_REQ_ACK(msg_p);
|
||||
nb_e_rabs_tobesetup = x2ap_handover_req_ack->nb_e_rabs_tobesetup;
|
||||
ue_context_p->ue_context.nb_x2u_e_rabs = nb_e_rabs_tobesetup;
|
||||
for(int i=0; i< nb_e_rabs_tobesetup; i++){
|
||||
ip_offset = 0;
|
||||
eps_bearer_id = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
|
||||
ue_context_p->ue_context.enb_gtp_x2u_ebi[i] = eps_bearer_id;
|
||||
ue_context_p->ue_context.enb_gtp_x2u_teid[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid;
|
||||
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid;
|
||||
|
||||
if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 4) ||
|
||||
(x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) {
|
||||
in_addr = *((in_addr_t*)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer);
|
||||
ip_offset = 4;
|
||||
gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr = in_addr;
|
||||
ue_context_p->ue_context.enb_gtp_x2u_addrs[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr;
|
||||
}
|
||||
|
||||
if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 16) ||
|
||||
(x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) {
|
||||
memcpy(gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip6_addr.s6_addr,
|
||||
&x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer[ip_offset],
|
||||
16);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rrc_eNB_process_handoverCommand(instance, ue_context_p, &X2AP_HANDOVER_REQ_ACK(msg_p));
|
||||
ue_context_p->ue_context.handover_info->state = HO_PREPARE;
|
||||
break;
|
||||
|
||||
@@ -27,14 +27,19 @@
|
||||
* \email: lionel.gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
//#if defined(ENABLE_USE_MME)
|
||||
# include "rrc_defs.h"
|
||||
# include "rrc_extern.h"
|
||||
# include "RRC/LTE/MESSAGES/asn1_msg.h"
|
||||
# include "rrc_eNB_GTPV1U.h"
|
||||
# include "rrc_eNB_UE_context.h"
|
||||
# include "msc.h"
|
||||
|
||||
//# if defined(ENABLE_ITTI)
|
||||
# include "asn1_conversions.h"
|
||||
# include "intertask_interface.h"
|
||||
//#endif
|
||||
|
||||
# include "common/ran_context.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
@@ -88,6 +93,88 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
boolean_t
|
||||
gtpv_data_req(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
uint8_t* const buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
uint32_t task_id
|
||||
)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
if(sdu_sizeP == 0)
|
||||
{
|
||||
LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0");
|
||||
return FALSE;
|
||||
}
|
||||
LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %d", ctxt_pP->rnti, sdu_sizeP, rb_idP);
|
||||
#if defined(ENABLE_ITTI)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
// Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
|
||||
uint8_t *message_buffer;
|
||||
|
||||
if(task_id == TASK_DATA_FORWARDING){
|
||||
|
||||
LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
|
||||
|
||||
message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
|
||||
|
||||
memcpy (message_buffer, buffer_pP, sdu_sizeP);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_IND);
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti;
|
||||
GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
|
||||
|
||||
itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p);
|
||||
return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
|
||||
}else if(task_id == TASK_END_MARKER){
|
||||
|
||||
LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
|
||||
|
||||
message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
|
||||
|
||||
memcpy (message_buffer, buffer_pP, sdu_sizeP);
|
||||
|
||||
message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_IND);
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti;
|
||||
GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
|
||||
|
||||
itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p);
|
||||
return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
|
||||
module_id_t enb_mod_idP,
|
||||
const rrc_eNB_ue_context_t* const ue_context_pP
|
||||
@@ -112,3 +199,5 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
|
||||
}
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,4 +53,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
|
||||
const rrc_eNB_ue_context_t* const ue_context_pP
|
||||
);
|
||||
|
||||
boolean_t
|
||||
gtpv_data_req(
|
||||
const protocol_ctxt_t* const ctxt_pP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
uint8_t* const buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
uint32_t task_id
|
||||
);
|
||||
|
||||
#endif /* RRC_ENB_GTPV1U_H_ */
|
||||
|
||||
@@ -2040,6 +2040,69 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_context_t* const ue_context_target_p) {
|
||||
gtpv1u_enb_create_x2u_tunnel_req_t create_tunnel_req;
|
||||
gtpv1u_enb_create_x2u_tunnel_resp_t create_tunnel_resp;
|
||||
uint8_t e_rab_done;
|
||||
uint8_t inde_list[NB_RB_MAX - 3]= {0};
|
||||
|
||||
if (ue_context_target_p == NULL) {
|
||||
|
||||
return (-1);
|
||||
} else {
|
||||
|
||||
/* Save e RAB information for later */
|
||||
{
|
||||
LOG_I(RRC, "[eNB %d] rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ: rnti %u nb_of_e_rabs %d\n",
|
||||
instance, ue_context_target_p->ue_context.rnti, ue_context_target_p->ue_context.nb_of_e_rabs);
|
||||
int i;
|
||||
memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
|
||||
uint8_t nb_e_rabs_tosetup = ue_context_target_p->ue_context.nb_of_e_rabs;
|
||||
e_rab_done = 0;
|
||||
|
||||
for (i = 0;i < nb_e_rabs_tosetup; i++) {
|
||||
|
||||
if(ue_context_target_p->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE)
|
||||
continue;
|
||||
|
||||
create_tunnel_req.eps_bearer_id[e_rab_done] = ue_context_target_p->ue_context.e_rab[i].param.e_rab_id;
|
||||
LOG_I(RRC,"x2 tunnel setup: local index %d UE id %x, eps id %d \n",
|
||||
i,
|
||||
ue_context_target_p->ue_context.rnti,
|
||||
create_tunnel_req.eps_bearer_id[i] );
|
||||
inde_list[i] = e_rab_done;
|
||||
e_rab_done++;
|
||||
}
|
||||
|
||||
create_tunnel_req.rnti = ue_context_target_p->ue_context.rnti; // warning put zero above
|
||||
create_tunnel_req.num_tunnels = e_rab_done;
|
||||
// NN: not sure if we should create a new tunnel: need to check teid, etc.
|
||||
gtpv1u_create_x2u_tunnel(
|
||||
instance,
|
||||
&create_tunnel_req,
|
||||
&create_tunnel_resp);
|
||||
|
||||
ue_context_target_p->ue_context.nb_x2u_e_rabs = create_tunnel_resp.num_tunnels;
|
||||
for (i = 0; i < create_tunnel_resp.num_tunnels; i++) {
|
||||
ue_context_target_p->ue_context.enb_gtp_x2u_teid[inde_list[i]] = create_tunnel_resp.enb_X2u_teid[i];
|
||||
ue_context_target_p->ue_context.enb_gtp_x2u_addrs[inde_list[i]] = create_tunnel_resp.enb_addr;
|
||||
ue_context_target_p->ue_context.enb_gtp_x2u_ebi[inde_list[i]] = create_tunnel_resp.eps_bearer_id[i];
|
||||
|
||||
LOG_I(RRC, "rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ tunnel (%u, %u) bearer UE context index %u, msg index %u, eps bearer id %u, gtp addr len %d \n",
|
||||
create_tunnel_resp.enb_X2u_teid[i],
|
||||
ue_context_target_p->ue_context.enb_gtp_x2u_teid[inde_list[i]],
|
||||
inde_list[i],
|
||||
i,
|
||||
create_tunnel_resp.eps_bearer_id[i],
|
||||
create_tunnel_resp.enb_addr.length);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance) {
|
||||
uint16_t ue_initial_id;
|
||||
uint32_t eNB_ue_s1ap_id;
|
||||
|
||||
@@ -278,6 +278,7 @@ int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t *const ctxt_p
|
||||
|
||||
int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *const ue_context_pP);
|
||||
int rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_context_t* const ue_context_target_p);
|
||||
int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance);
|
||||
|
||||
int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP);
|
||||
|
||||
@@ -173,6 +173,8 @@ typedef struct x2ap_eNB_instance_s {
|
||||
lte_frame_type_t frame_type[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
|
||||
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
|
||||
uint32_t subframeAssignment[MAX_NUM_CCs];
|
||||
uint32_t specialSubframe[MAX_NUM_CCs];
|
||||
int num_cc;
|
||||
|
||||
net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS];
|
||||
|
||||
@@ -144,7 +144,92 @@ int x2ap_eNB_generate_x2_setup_request(
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"X2Setuprequest not supported for TDD!");
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
|
||||
@@ -279,7 +364,92 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eN
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"X2Setupresponse not supported for TDD!");
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
|
||||
@@ -627,6 +797,27 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p,
|
||||
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);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
|
||||
}
|
||||
|
||||
@@ -749,6 +749,8 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
|
||||
{
|
||||
X2AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck;
|
||||
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;
|
||||
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
@@ -816,6 +818,56 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
|
||||
|
||||
X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti;
|
||||
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
|
||||
X2AP_ProtocolIE_ID_id_E_RABs_Admitted_List, true);
|
||||
|
||||
if (ie == NULL ) {
|
||||
X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}else{
|
||||
if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) {
|
||||
|
||||
uint8_t nb_e_rabs_tobesetup;
|
||||
nb_e_rabs_tobesetup = ie->value.choice.E_RABs_Admitted_List.list.count;
|
||||
X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = nb_e_rabs_tobesetup;
|
||||
|
||||
for (int i=0; i<nb_e_rabs_tobesetup; i++) {
|
||||
e_RABS_Admitted_ItemIEs = (X2AP_E_RABs_Admitted_ItemIEs_t *) ie->value.choice.E_RABs_Admitted_List.list.array[i];
|
||||
e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
|
||||
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_Admitted_Item->e_RAB_ID ;
|
||||
X2AP_ERROR("x2u tunnel: index %d e_rab_id %d\n", i, X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id);
|
||||
|
||||
if(e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint == NULL){
|
||||
X2AP_DEBUG("%s %d: X2AP_E_RABs_Admitted_Item_t->dL_GTP_TunnelEndpoint is a NULL pointer \n", __FILE__, __LINE__);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer,
|
||||
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf,
|
||||
e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size);
|
||||
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.length = e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size;
|
||||
|
||||
OCTET_STRING_TO_INT32(&e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->gTP_TEID,
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid);
|
||||
|
||||
|
||||
X2AP_DEBUG("x2u tunnel: index %d target enb ip %d.%d.%d.%d length %d gtp teid %u\n",
|
||||
i,
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[0],
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[1],
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[2],
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[3],
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.length,
|
||||
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
|
||||
X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user