X2AP UE Context Release (generate/handle message), Release eNB resources
This commit is contained in:
committed by
Cedric Roux
parent
4b5c42115d
commit
52a52eefb9
@@ -40,3 +40,6 @@ MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_der
|
||||
/* handover messages X2AP <-> RRC */
|
||||
MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req)
|
||||
MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack)
|
||||
|
||||
/* handover messages X2AP <-> S1AP */
|
||||
MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release)
|
||||
|
||||
@@ -33,11 +33,20 @@
|
||||
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
|
||||
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
|
||||
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
|
||||
#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
|
||||
|
||||
|
||||
#define X2AP_MAX_NB_ENB_IP_ADDRESS 2
|
||||
|
||||
// eNB application layer -> X2AP messages
|
||||
|
||||
/* X2AP UE CONTEXT RELEASE */
|
||||
typedef struct x2ap_ue_context_release_s {
|
||||
int old_eNB_ue_x2ap_id;
|
||||
int new_eNB_ue_x2ap_id;
|
||||
int target_mod_id;
|
||||
} x2ap_ue_context_release_t;
|
||||
|
||||
typedef struct x2ap_register_enb_req_s {
|
||||
/* Unique eNB_id to identify the eNB within EPC.
|
||||
* For macro eNB ids this field should be 20 bits long.
|
||||
|
||||
@@ -343,7 +343,8 @@ typedef enum HO_STATE_e {
|
||||
HO_COMPLETE, // initiated by the target eNB
|
||||
HO_REQUEST,
|
||||
HO_ACK,
|
||||
HO_CONFIGURED
|
||||
HO_CONFIGURED,
|
||||
HO_RELEASE
|
||||
} HO_STATE_t;
|
||||
|
||||
typedef enum SL_TRIGGER_e {
|
||||
|
||||
@@ -4223,6 +4223,42 @@ void rrc_eNB_process_handoverCommand(
|
||||
ue_context->ue_context.handover_info->size = size;
|
||||
}
|
||||
|
||||
void rrc_eNB_handover_ue_context_release(
|
||||
protocol_ctxt_t *const ctxt_pP,
|
||||
struct rrc_eNB_ue_context_s *ue_context_p) {
|
||||
int e_rab = 0;
|
||||
//MessageDef *msg_release_p = NULL;
|
||||
MessageDef *msg_delete_tunnels_p = NULL;
|
||||
uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
|
||||
|
||||
//msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE);
|
||||
//itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_release_p);
|
||||
s1ap_ue_context_release(ctxt_pP->instance, ue_context_p->ue_context.eNB_ue_s1ap_id);
|
||||
|
||||
//MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
|
||||
msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
|
||||
memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
|
||||
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
|
||||
|
||||
for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
|
||||
GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab];
|
||||
// erase data
|
||||
ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
|
||||
memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
|
||||
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
|
||||
}
|
||||
|
||||
itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
|
||||
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
|
||||
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
|
||||
|
||||
if (rrc_ue_s1ap_ids != NULL) {
|
||||
rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
@@ -7990,6 +8026,14 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.handover_info != NULL) {
|
||||
if (ue_context_p->ue_context.handover_info->state == HO_RELEASE) {
|
||||
ue_to_be_removed = ue_context_p;
|
||||
rrc_eNB_handover_ue_context_release(ctxt_pP, ue_context_p);
|
||||
break; //break RB_FOREACH (why to break ?)
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&rrc_release_freelist);
|
||||
|
||||
if (rrc_release_info.num_UEs > 0) {
|
||||
@@ -8161,6 +8205,9 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
SRB_INFO *srb_info_p;
|
||||
int CC_id;
|
||||
protocol_ctxt_t ctxt;
|
||||
|
||||
// memset(&ctxt, 0, sizeof(ctxt));
|
||||
|
||||
// Wait for a message
|
||||
itti_receive_msg(TASK_RRC_ENB, &msg_p);
|
||||
msg_name_p = ITTI_MSG_NAME(msg_p);
|
||||
@@ -8278,7 +8325,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
//LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n",
|
||||
//instance, msg_name_p);
|
||||
if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)
|
||||
&& rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) {
|
||||
&& rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0
|
||||
&& rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.handover_info->state != HO_RELEASE) {
|
||||
rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc =
|
||||
rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc;
|
||||
}
|
||||
@@ -8310,6 +8358,19 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
|
||||
break;
|
||||
}
|
||||
|
||||
case X2AP_UE_CONTEXT_RELEASE: {
|
||||
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
|
||||
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti);
|
||||
LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s at frame %d subframe %d \n", instance, msg_name_p,
|
||||
ctxt.frame,ctxt.subframe);
|
||||
DevAssert(ue_context_p != NULL);
|
||||
|
||||
if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort();
|
||||
|
||||
ue_context_p->ue_context.handover_info->state = HO_RELEASE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Messages from eNB app */
|
||||
case RRC_CONFIGURATION_REQ:
|
||||
LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p,&RRC_CONFIGURATION_REQ(msg_p));
|
||||
|
||||
@@ -2087,9 +2087,60 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
|
||||
/* Security key */
|
||||
ue_context_p->ue_context.next_hop_chain_count=S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_hop_chain_count;
|
||||
memcpy ( ue_context_p->ue_context.next_security_key,
|
||||
S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_security_key,
|
||||
SECURITY_KEY_LENGTH);
|
||||
S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_security_key,
|
||||
SECURITY_KEY_LENGTH);
|
||||
|
||||
rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(&ctxt, ue_context_p);
|
||||
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP) {
|
||||
|
||||
MessageDef *msg_p = NULL;
|
||||
|
||||
msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE);
|
||||
|
||||
X2AP_UE_CONTEXT_RELEASE (msg_p).old_eNB_ue_x2ap_id = 0;
|
||||
X2AP_UE_CONTEXT_RELEASE (msg_p).new_eNB_ue_x2ap_id = 0;
|
||||
X2AP_UE_CONTEXT_RELEASE (msg_p).target_mod_id = ue_context_pP->ue_context.handover_info->modid_t;
|
||||
itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id){
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
|
||||
struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
|
||||
|
||||
s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
|
||||
DevAssert(s1ap_eNB_instance_p != NULL);
|
||||
|
||||
if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
|
||||
eNB_ue_s1ap_id)) == NULL) {
|
||||
/* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
|
||||
LOG_W(RRC,"Failed to find ue context associated with eNB ue s1ap id: %u\n",
|
||||
eNB_ue_s1ap_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// release UE context
|
||||
struct s1ap_eNB_ue_context_s *ue_context2_p = NULL;
|
||||
|
||||
if ((ue_context2_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_context_p))
|
||||
!= NULL) {
|
||||
LOG_W(RRC,"Removed UE context eNB_ue_s1ap_id %u\n",
|
||||
ue_context2_p->eNB_ue_s1ap_id);
|
||||
s1ap_eNB_free_ue_context(ue_context2_p);
|
||||
} else {
|
||||
LOG_W(RRC,"Removing UE context eNB_ue_s1ap_id %u: did not find context\n",
|
||||
ue_context_p->eNB_ue_s1ap_id);
|
||||
}
|
||||
/*RB_FOREACH(ue_context_p, s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head) {
|
||||
S1AP_WARN("in s1ap_ue_map: UE context eNB_ue_s1ap_id %u mme_ue_s1ap_id %u state %u\n",
|
||||
ue_context_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,
|
||||
ue_context_p->ue_state);
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -270,4 +270,8 @@ 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_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);
|
||||
|
||||
int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id);
|
||||
|
||||
#endif /* RRC_ENB_S1AP_H_ */
|
||||
|
||||
@@ -79,6 +79,11 @@ static
|
||||
void x2ap_eNB_handle_handover_req_ack(instance_t instance,
|
||||
x2ap_handover_req_ack_t *x2ap_handover_req_ack);
|
||||
|
||||
static
|
||||
void x2ap_eNB_handle_ue_context_release(instance_t instance,
|
||||
x2ap_ue_context_release_t *x2ap_ue_context_release);
|
||||
|
||||
|
||||
static
|
||||
void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
|
||||
int result;
|
||||
@@ -423,6 +428,23 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance,
|
||||
//x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size);
|
||||
}
|
||||
|
||||
static
|
||||
void x2ap_eNB_handle_ue_context_release(instance_t instance,
|
||||
x2ap_ue_context_release_t *x2ap_ue_context_release)
|
||||
{
|
||||
x2ap_eNB_instance_t *instance_p;
|
||||
x2ap_eNB_data_t *target;
|
||||
int target_enb_id = x2ap_ue_context_release->target_mod_id;
|
||||
|
||||
instance_p = x2ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
|
||||
target = x2ap_is_eNB_id_in_list(target_enb_id);
|
||||
DevAssert(target != NULL);
|
||||
|
||||
x2ap_eNB_generate_x2_ue_context_release(target, x2ap_ue_context_release);
|
||||
}
|
||||
|
||||
void *x2ap_task(void *arg) {
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
@@ -454,6 +476,11 @@ void *x2ap_task(void *arg) {
|
||||
&X2AP_HANDOVER_REQ_ACK(received_msg));
|
||||
break;
|
||||
|
||||
case X2AP_UE_CONTEXT_RELEASE:
|
||||
x2ap_eNB_handle_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&X2AP_UE_CONTEXT_RELEASE(received_msg));
|
||||
break;
|
||||
|
||||
case SCTP_INIT_MSG_MULTI_CNF:
|
||||
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
|
||||
|
||||
@@ -48,6 +48,10 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
|
||||
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu);
|
||||
X2AP_INFO("x2ap_eNB_decode_initiating_message!\n");
|
||||
break;
|
||||
case X2AP_ProcedureCode_id_uEContextRelease:
|
||||
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu);
|
||||
X2AP_INFO("x2ap_eNB_decode_initiating_message!\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
|
||||
|
||||
@@ -619,8 +619,8 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
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;
|
||||
ie->value.choice.UE_X2AP_ID = 0;
|
||||
ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1;
|
||||
ie->value.choice.UE_X2AP_ID_1 = 0;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
/* mandatory */
|
||||
@@ -668,7 +668,7 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p)
|
||||
int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release)
|
||||
{
|
||||
|
||||
X2AP_X2AP_PDU_t pdu;
|
||||
@@ -701,15 +701,15 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p)
|
||||
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 = 0;
|
||||
ie->value.choice.UE_X2AP_ID = x2ap_ue_context_release->old_eNB_ue_x2ap_id;
|
||||
ASN_SEQUENCE_ADD(&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;
|
||||
ie->value.choice.UE_X2AP_ID = 0;
|
||||
ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1;
|
||||
ie->value.choice.UE_X2AP_ID_1 = x2ap_ue_context_release->new_eNB_ue_x2ap_id;
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
|
||||
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||
|
||||
@@ -53,6 +53,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
x2ap_handover_req_ack_t *x2ap_handover_req_ack);
|
||||
|
||||
int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p);
|
||||
int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p,
|
||||
x2ap_ue_context_release_t *x2ap_ue_context_release);
|
||||
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
|
||||
|
||||
|
||||
@@ -71,6 +71,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
static
|
||||
int x2ap_eNB_handle_ue_context_release (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu);
|
||||
|
||||
/* Handlers matrix. Only eNB related procedure present here */
|
||||
x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
{ x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */
|
||||
@@ -78,7 +84,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
|
||||
{ 0, 0, 0 }, /* loadIndication */
|
||||
{ 0, 0, 0 }, /* errorIndication */
|
||||
{ 0, 0, 0 }, /* snStatusTransfer */
|
||||
{ 0, 0, 0 }, /* uEContextRelease */
|
||||
{ x2ap_eNB_handle_ue_context_release, 0, 0 }, /* uEContextRelease */
|
||||
{ x2ap_eNB_handle_x2_setup_request, x2ap_eNB_handle_x2_setup_response, x2ap_eNB_handle_x2_setup_failure }, /* x2Setup */
|
||||
{ 0, 0, 0 }, /* reset */
|
||||
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
|
||||
@@ -726,3 +732,47 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int x2ap_eNB_handle_ue_context_release (instance_t instance,
|
||||
uint32_t assoc_id,
|
||||
uint32_t stream,
|
||||
X2AP_X2AP_PDU_t *pdu)
|
||||
{
|
||||
X2AP_UEContextRelease_t *x2UEContextRelease;
|
||||
X2AP_UEContextRelease_IEs_t *ie;
|
||||
|
||||
x2ap_eNB_data_t *x2ap_eNB_data;
|
||||
MessageDef *msg;
|
||||
|
||||
DevAssert (pdu != NULL);
|
||||
x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease;
|
||||
|
||||
if (stream == 0) {
|
||||
X2AP_ERROR ("Received new x2 ue context release on stream == 0\n");
|
||||
/* TODO: send a x2 failure response */
|
||||
return 0;
|
||||
}
|
||||
|
||||
X2AP_DEBUG ("Received a new X2 ue context release\n");
|
||||
|
||||
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
|
||||
DevAssert(x2ap_eNB_data != NULL);
|
||||
|
||||
msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE);
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease,
|
||||
X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
|
||||
|
||||
X2AP_UE_CONTEXT_RELEASE(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease,
|
||||
X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true);
|
||||
|
||||
X2AP_UE_CONTEXT_RELEASE(msg).new_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID;
|
||||
|
||||
itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user