From d0fd6c4a7313e3214dcaf705aa5687dfbfffddd0 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Fri, 15 Sep 2017 13:28:07 +0900 Subject: [PATCH] add ho failure and ho prep failure... All done --- lib/s1ap/s1ap_free.c | 10 +- src/mme/mme_context.c | 32 ++++- src/mme/mme_context.h | 1 + src/mme/mme_s11_handler.c | 2 + src/mme/s1ap_build.c | 255 +++++++++++++++++++++----------------- src/mme/s1ap_build.h | 7 +- src/mme/s1ap_handler.c | 46 ++++++- src/mme/s1ap_path.c | 103 +++++++++------ src/mme/s1ap_path.h | 6 +- 9 files changed, 298 insertions(+), 164 deletions(-) diff --git a/lib/s1ap/s1ap_free.c b/lib/s1ap/s1ap_free.c index 970199365..9d5cbae6c 100644 --- a/lib/s1ap/s1ap_free.c +++ b/lib/s1ap/s1ap_free.c @@ -216,16 +216,16 @@ static inline int s1ap_free_unsuccessfull_outcome(s1ap_message_t *message) &message->s1ap_PathSwitchRequestFailureIEs); break; - case S1ap_ProcedureCode_id_HandoverResourceAllocation: - s1ap_free_s1ap_handoverfailureies( - &message->s1ap_HandoverFailureIEs); - break; - case S1ap_ProcedureCode_id_HandoverPreparation: s1ap_free_s1ap_handoverpreparationfailureies( &message->s1ap_HandoverPreparationFailureIEs); break; + case S1ap_ProcedureCode_id_HandoverResourceAllocation: + s1ap_free_s1ap_handoverfailureies( + &message->s1ap_HandoverFailureIEs); + break; + default: d_warn("Unknown procedure ID (%d) for unsuccessfull " "outcome message\n", (int)message->procedureCode); diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index 78b0d14af..7c8303617 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -1498,14 +1498,40 @@ status_t mme_ue_associate_target_ue(mme_ue_t *mme_ue, enb_ue_t *target_ue) } /* - * mme_ue is deassociated with source like the following conditions + * mme_ue is deassociated with target_ue like the following conditions * - * UE Context Release Complete : enb_ue_remove() + * Handover Cancel -> Delete Indirect Tunnel -> Deassociate -> UL Relase + * Handover Cancel -> Deassociate -> UL Relase + * S1AP Handover Failure + */ +status_t mme_ue_deassociate_target_ue(enb_ue_t *target_ue) +{ + enb_ue_t *source_ue = NULL; + + d_assert(target_ue, return CORE_ERROR,); + + target_ue->mme_ue = NULL; + target_ue->source_ue = NULL; + + source_ue = target_ue->source_ue; + if (source_ue) + source_ue->target_ue = NULL; + + return CORE_OK; +} + +/* + * mme_ue is deassociated with source_ue like the following conditions + * + * S1AP UE Context Release Complete : enb_ue_remove() */ status_t mme_ue_deassociate_source_ue(enb_ue_t *source_ue) { - enb_ue_t *target_ue = source_ue->target_ue; + enb_ue_t *target_ue = NULL; + + d_assert(source_ue, return CORE_ERROR,); + target_ue = source_ue->target_ue; if (target_ue) target_ue->source_ue = NULL; else if (source_ue->mme_ue) diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index df7fab482..7ab00f3ba 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -469,6 +469,7 @@ CORE_DECLARE(status_t) mme_ue_associate_enb_ue( mme_ue_t *mme_ue, enb_ue_t *enb_ue); CORE_DECLARE(status_t) mme_ue_associate_target_ue( mme_ue_t *mme_ue, enb_ue_t *target_ue); +CORE_DECLARE(status_t) mme_ue_deassociate_target_ue(enb_ue_t *target_ue); CORE_DECLARE(status_t) mme_ue_deassociate_source_ue(enb_ue_t *source_ue); CORE_DECLARE(hash_index_t *) mme_ue_first(); diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index f25bf1f34..1201a0f38 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -471,6 +471,8 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response( target_ue = source_ue->target_ue; d_assert(target_ue, return, "Null param"); + mme_ue_deassociate_target_ue(target_ue); + cause.present = S1ap_Cause_PR_radioNetwork; cause.choice.nas = S1ap_CauseRadioNetwork_handover_cancelled; diff --git a/src/mme/s1ap_build.c b/src/mme/s1ap_build.c index ff2c07677..769748420 100644 --- a/src/mme/s1ap_build.c +++ b/src/mme/s1ap_build.c @@ -674,6 +674,150 @@ status_t s1ap_build_path_switch_failure(pkbuf_t **s1apbuf, return CORE_OK; } +status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue) +{ + char buf[INET_ADDRSTRLEN]; + + int encoded; + s1ap_message_t message; + S1ap_HandoverCommandIEs_t *ies = &message.s1ap_HandoverCommandIEs; + S1ap_E_RABDataForwardingItem_t *e_rab = NULL; + + mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; + mme_bearer_t *bearer = NULL; + + d_assert(source_ue, return CORE_ERROR, "Null param"); + mme_ue = source_ue->mme_ue; + + memset(&message, 0, sizeof(s1ap_message_t)); + + ies->mme_ue_s1ap_id = source_ue->mme_ue_s1ap_id; + ies->eNB_UE_S1AP_ID = source_ue->enb_ue_s1ap_id; + ies->handoverType = source_ue->handover_type; + + sess = mme_sess_first(mme_ue); + while(sess) + { + bearer = mme_bearer_first(sess); + while(bearer) + { + if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) || + MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) + { + e_rab = (S1ap_E_RABDataForwardingItem_t *) + core_calloc(1, sizeof(S1ap_E_RABDataForwardingItem_t)); + e_rab->e_RAB_ID = bearer->ebi; + } + + if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer)) + { + e_rab->dL_transportLayerAddress = + (S1ap_TransportLayerAddress_t *) + core_calloc(1, sizeof(S1ap_TransportLayerAddress_t)); + e_rab->dL_transportLayerAddress->size = 4; + e_rab->dL_transportLayerAddress->buf = core_calloc( + e_rab->dL_transportLayerAddress->size, sizeof(c_uint8_t)); + memcpy(e_rab->dL_transportLayerAddress->buf, + &bearer->sgw_dl_addr, + e_rab->dL_transportLayerAddress->size); + + e_rab->dL_gTP_TEID = (S1ap_GTP_TEID_t *) + core_calloc(1, sizeof(S1ap_GTP_TEID_t)); + s1ap_uint32_to_OCTET_STRING( + bearer->sgw_dl_teid, e_rab->dL_gTP_TEID); + } + + if (MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) + { + e_rab->uL_S1ap_TransportLayerAddress = + (S1ap_TransportLayerAddress_t *) + core_calloc(1, sizeof(S1ap_TransportLayerAddress_t)); + e_rab->uL_S1ap_TransportLayerAddress->size = 4; + e_rab->uL_S1ap_TransportLayerAddress->buf = core_calloc( + e_rab->uL_S1ap_TransportLayerAddress->size, + sizeof(c_uint8_t)); + memcpy(e_rab->uL_S1ap_TransportLayerAddress->buf, + &bearer->sgw_ul_addr, + e_rab->uL_S1ap_TransportLayerAddress->size); + + e_rab->uL_S1ap_GTP_TEID = (S1ap_GTP_TEID_t *) + core_calloc(1, sizeof(S1ap_GTP_TEID_t)); + s1ap_uint32_to_OCTET_STRING( + bearer->sgw_ul_teid, e_rab->uL_S1ap_GTP_TEID); + } + + if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) || + MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) + { + ASN_SEQUENCE_ADD(&ies->e_RABDataForwardingList, e_rab); + } + + bearer = mme_bearer_next(bearer); + } + sess = mme_sess_next(sess); + } + + if (ies->e_RABDataForwardingList.s1ap_E_RABDataForwardingItem.count) + { + ies->presenceMask |= + S1AP_HANDOVERCOMMANDIES_E_RABDATAFORWARDINGLIST_PRESENT; + } + + s1ap_buffer_to_OCTET_STRING(mme_ue->container.buf, mme_ue->container.size, + &ies->target_ToSource_TransparentContainer); + S1AP_CLEAR_DATA(&mme_ue->container); + + message.procedureCode = S1ap_ProcedureCode_id_HandoverPreparation; + message.direction = S1AP_PDU_PR_successfulOutcome; + + encoded = s1ap_encode_pdu(s1apbuf, &message); + s1ap_free_pdu(&message); + + d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,); + + d_trace(3, "[S1AP] Handover Command : ", + "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n", + source_ue->mme_ue_s1ap_id, + INET_NTOP(&source_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf), + source_ue->enb->enb_id); + + return CORE_OK; +} + +status_t s1ap_build_handover_preparation_failure( + pkbuf_t **s1apbuf, enb_ue_t *source_ue, S1ap_Cause_t *cause) +{ + char buf[INET_ADDRSTRLEN]; + + int encoded; + s1ap_message_t message; + S1ap_HandoverPreparationFailureIEs_t *ies = + &message.s1ap_HandoverPreparationFailureIEs; + + memset(&message, 0, sizeof(s1ap_message_t)); + + ies->mme_ue_s1ap_id = source_ue->mme_ue_s1ap_id; + ies->eNB_UE_S1AP_ID = source_ue->enb_ue_s1ap_id; + s1ap_build_cause(&ies->cause, cause); + + message.procedureCode = S1ap_ProcedureCode_id_HandoverPreparation; + message.direction = S1AP_PDU_PR_unsuccessfulOutcome; + + encoded = s1ap_encode_pdu(s1apbuf, &message); + s1ap_free_pdu(&message); + + d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,); + + d_trace(3, "[S1AP] Handover Preparation Failure : ", + "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n", + source_ue->mme_ue_s1ap_id, + INET_NTOP(&source_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf), + source_ue->enb->enb_id); + + return CORE_OK; +} + status_t s1ap_build_handover_request( pkbuf_t **s1apbuf, mme_ue_t *mme_ue, enb_ue_t *target_ue, S1ap_HandoverRequiredIEs_t *required) @@ -817,117 +961,6 @@ status_t s1ap_build_handover_request( return CORE_OK; } -status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue) -{ - char buf[INET_ADDRSTRLEN]; - - int encoded; - s1ap_message_t message; - S1ap_HandoverCommandIEs_t *ies = &message.s1ap_HandoverCommandIEs; - S1ap_E_RABDataForwardingItem_t *e_rab = NULL; - - mme_ue_t *mme_ue = NULL; - mme_sess_t *sess = NULL; - mme_bearer_t *bearer = NULL; - - d_assert(source_ue, return CORE_ERROR, "Null param"); - mme_ue = source_ue->mme_ue; - - memset(&message, 0, sizeof(s1ap_message_t)); - - ies->mme_ue_s1ap_id = source_ue->mme_ue_s1ap_id; - ies->eNB_UE_S1AP_ID = source_ue->enb_ue_s1ap_id; - ies->handoverType = source_ue->handover_type; - - sess = mme_sess_first(mme_ue); - while(sess) - { - bearer = mme_bearer_first(sess); - while(bearer) - { - if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) || - MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) - { - e_rab = (S1ap_E_RABDataForwardingItem_t *) - core_calloc(1, sizeof(S1ap_E_RABDataForwardingItem_t)); - e_rab->e_RAB_ID = bearer->ebi; - } - - if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer)) - { - e_rab->dL_transportLayerAddress = - (S1ap_TransportLayerAddress_t *) - core_calloc(1, sizeof(S1ap_TransportLayerAddress_t)); - e_rab->dL_transportLayerAddress->size = 4; - e_rab->dL_transportLayerAddress->buf = core_calloc( - e_rab->dL_transportLayerAddress->size, sizeof(c_uint8_t)); - memcpy(e_rab->dL_transportLayerAddress->buf, - &bearer->sgw_dl_addr, - e_rab->dL_transportLayerAddress->size); - - e_rab->dL_gTP_TEID = (S1ap_GTP_TEID_t *) - core_calloc(1, sizeof(S1ap_GTP_TEID_t)); - s1ap_uint32_to_OCTET_STRING( - bearer->sgw_dl_teid, e_rab->dL_gTP_TEID); - } - - if (MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) - { - e_rab->uL_S1ap_TransportLayerAddress = - (S1ap_TransportLayerAddress_t *) - core_calloc(1, sizeof(S1ap_TransportLayerAddress_t)); - e_rab->uL_S1ap_TransportLayerAddress->size = 4; - e_rab->uL_S1ap_TransportLayerAddress->buf = core_calloc( - e_rab->uL_S1ap_TransportLayerAddress->size, - sizeof(c_uint8_t)); - memcpy(e_rab->uL_S1ap_TransportLayerAddress->buf, - &bearer->sgw_ul_addr, - e_rab->uL_S1ap_TransportLayerAddress->size); - - e_rab->uL_S1ap_GTP_TEID = (S1ap_GTP_TEID_t *) - core_calloc(1, sizeof(S1ap_GTP_TEID_t)); - s1ap_uint32_to_OCTET_STRING( - bearer->sgw_ul_teid, e_rab->uL_S1ap_GTP_TEID); - } - - if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) || - MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) - { - ASN_SEQUENCE_ADD(&ies->e_RABDataForwardingList, e_rab); - } - - bearer = mme_bearer_next(bearer); - } - sess = mme_sess_next(sess); - } - - if (ies->e_RABDataForwardingList.s1ap_E_RABDataForwardingItem.count) - { - ies->presenceMask |= - S1AP_HANDOVERCOMMANDIES_E_RABDATAFORWARDINGLIST_PRESENT; - } - - s1ap_buffer_to_OCTET_STRING(mme_ue->container.buf, mme_ue->container.size, - &ies->target_ToSource_TransparentContainer); - S1AP_CLEAR_DATA(&mme_ue->container); - - message.procedureCode = S1ap_ProcedureCode_id_HandoverPreparation; - message.direction = S1AP_PDU_PR_successfulOutcome; - - encoded = s1ap_encode_pdu(s1apbuf, &message); - s1ap_free_pdu(&message); - - d_assert(s1apbuf && encoded >= 0,return CORE_ERROR,); - - d_trace(3, "[S1AP] Handover Command : ", - "UE[mME-UE-S1AP-ID(%d)] <-- eNB[%s:%d]\n", - source_ue->mme_ue_s1ap_id, - INET_NTOP(&source_ue->enb->s1ap_sock->remote.sin_addr.s_addr, buf), - source_ue->enb->enb_id); - - return CORE_OK; -} - status_t s1ap_build_handover_cancel_ack(pkbuf_t **s1apbuf, enb_ue_t *source_ue) { char buf[INET_ADDRSTRLEN]; diff --git a/src/mme/s1ap_build.h b/src/mme/s1ap_build.h index dbba2562a..09e59221e 100644 --- a/src/mme/s1ap_build.h +++ b/src/mme/s1ap_build.h @@ -28,12 +28,15 @@ CORE_DECLARE(status_t) s1ap_build_path_switch_ack( CORE_DECLARE(status_t) s1ap_build_path_switch_failure(pkbuf_t **s1apbuf, c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id, S1ap_Cause_t *cause); +CORE_DECLARE(status_t) s1ap_build_handover_command( + pkbuf_t **s1apbuf, enb_ue_t *source_ue); +CORE_DECLARE(status_t) s1ap_build_handover_preparation_failure( + pkbuf_t **s1apbuf, enb_ue_t *source_ue, S1ap_Cause_t *cause); + CORE_DECLARE(status_t) s1ap_build_handover_request( pkbuf_t **s1apbuf, mme_ue_t *mme_ue, enb_ue_t *target_ue, S1ap_HandoverRequiredIEs_t *required); -CORE_DECLARE(status_t) s1ap_build_handover_command( - pkbuf_t **s1apbuf, enb_ue_t *source_ue); CORE_DECLARE(status_t) s1ap_build_handover_cancel_ack( pkbuf_t **s1apbuf, enb_ue_t *source_ue); diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index e7524319c..0c39d4451 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -680,7 +680,10 @@ void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message) } else { - d_assert(0, return,); + rv = s1ap_send_handover_preparation_failure(source_ue, &ies->cause); + d_assert(rv == CORE_OK, return, "s1ap send error"); + + return; } source_ue->handover_type = ies->handoverType; @@ -792,7 +795,44 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message) void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message) { - d_error("Not implemented"); + status_t rv; + char buf[INET_ADDRSTRLEN]; + + S1ap_HandoverFailureIEs_t *ies = NULL; + S1ap_Cause_t cause; + enb_ue_t *target_ue = NULL; + enb_ue_t *source_ue = NULL; + + d_assert(enb, return,); + + ies = &message->s1ap_HandoverFailureIEs; + d_assert(ies, return,); + + target_ue = enb_ue_find_by_mme_ue_s1ap_id(ies->mme_ue_s1ap_id); + d_assert(target_ue, return, + "Cannot find UE for MME-UE-S1AP-ID[%d] and eNB[%s:%d]", + ies->mme_ue_s1ap_id, + INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf), + enb->enb_id); + + source_ue = target_ue->source_ue; + d_assert(source_ue, return,); + rv = s1ap_send_handover_preparation_failure(source_ue, &ies->cause); + d_assert(rv == CORE_OK, return, "s1ap send error"); + + mme_ue_deassociate_target_ue(target_ue); + + cause.present = S1ap_Cause_PR_radioNetwork; + cause.choice.nas = S1ap_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system; + + rv = s1ap_send_ue_context_release_commmand(target_ue, &cause); + d_assert(rv == CORE_OK, return, "s1ap send error"); + + d_trace(3, "[S1AP] Handover Failure : " + "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n", + target_ue->enb_ue_s1ap_id, + INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf), + enb->enb_id); } void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message) @@ -862,6 +902,8 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message) target_ue = source_ue->target_ue; d_assert(target_ue, return,); + + mme_ue_deassociate_target_ue(target_ue); cause.present = S1ap_Cause_PR_radioNetwork; cause.choice.nas = S1ap_CauseRadioNetwork_handover_cancelled; diff --git a/src/mme/s1ap_path.c b/src/mme/s1ap_path.c index c6782d69e..b1eb7274a 100644 --- a/src/mme/s1ap_path.c +++ b/src/mme/s1ap_path.c @@ -424,6 +424,69 @@ status_t s1ap_send_path_switch_failure(mme_enb_t *enb, return rv; } + +status_t s1ap_send_handover_command(enb_ue_t *source_ue) +{ + status_t rv; + pkbuf_t *s1apbuf = NULL; + + mme_enb_t *enb = NULL; + + d_assert(source_ue, return CORE_ERROR,); + enb = source_ue->enb; + d_assert(enb, return CORE_ERROR,); + + rv = s1ap_build_handover_command(&s1apbuf, source_ue); + d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); + + rv = s1ap_send_to_enb(enb, s1apbuf); + d_assert(rv == CORE_OK,, "s1ap send error"); + + return rv; +} + +status_t s1ap_send_handover_preparation_failure( + enb_ue_t *source_ue, S1ap_Cause_t *cause) +{ + status_t rv; + pkbuf_t *s1apbuf = NULL; + + mme_enb_t *enb = NULL; + + d_assert(source_ue, return CORE_ERROR,); + enb = source_ue->enb; + d_assert(enb, return CORE_ERROR,); + + rv = s1ap_build_handover_preparation_failure(&s1apbuf, source_ue, cause); + d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); + + rv = s1ap_send_to_enb(enb, s1apbuf); + d_assert(rv == CORE_OK,, "s1ap send error"); + + return rv; +} + +status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue) +{ + status_t rv; + pkbuf_t *s1apbuf = NULL; + + mme_enb_t *enb = NULL; + + d_assert(source_ue, return CORE_ERROR,); + enb = source_ue->enb; + d_assert(enb, return CORE_ERROR,); + + rv = s1ap_build_handover_cancel_ack(&s1apbuf, source_ue); + d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); + + rv = s1ap_send_to_enb(enb, s1apbuf); + d_assert(rv == CORE_OK,, "s1ap send error"); + + return rv; +} + + status_t s1ap_send_handover_request( mme_ue_t *mme_ue, S1ap_HandoverRequiredIEs_t *ies) { @@ -481,46 +544,6 @@ status_t s1ap_send_handover_request( return rv; } -status_t s1ap_send_handover_command(enb_ue_t *source_ue) -{ - status_t rv; - pkbuf_t *s1apbuf = NULL; - - mme_enb_t *enb = NULL; - - d_assert(source_ue, return CORE_ERROR,); - enb = source_ue->enb; - d_assert(enb, return CORE_ERROR,); - - rv = s1ap_build_handover_command(&s1apbuf, source_ue); - d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); - - rv = s1ap_send_to_enb(enb, s1apbuf); - d_assert(rv == CORE_OK,, "s1ap send error"); - - return rv; -} - -status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue) -{ - status_t rv; - pkbuf_t *s1apbuf = NULL; - - mme_enb_t *enb = NULL; - - d_assert(source_ue, return CORE_ERROR,); - enb = source_ue->enb; - d_assert(enb, return CORE_ERROR,); - - rv = s1ap_build_handover_cancel_ack(&s1apbuf, source_ue); - d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); - - rv = s1ap_send_to_enb(enb, s1apbuf); - d_assert(rv == CORE_OK,, "s1ap send error"); - - return rv; -} - status_t s1ap_send_mme_status_transfer( enb_ue_t *target_ue, S1ap_ENBStatusTransferIEs_t *ies) { diff --git a/src/mme/s1ap_path.h b/src/mme/s1ap_path.h index 368ce12a0..1f9ff3243 100644 --- a/src/mme/s1ap_path.h +++ b/src/mme/s1ap_path.h @@ -29,9 +29,13 @@ CORE_DECLARE(status_t) s1ap_send_path_switch_ack(mme_ue_t *mme_ue); CORE_DECLARE(status_t) s1ap_send_path_switch_failure(mme_enb_t *enb, c_uint32_t enb_ue_s1ap_id, c_uint32_t mme_ue_s1ap_id, S1ap_Cause_t *cause); +CORE_DECLARE(status_t) s1ap_send_handover_command(enb_ue_t *source_ue); +CORE_DECLARE(status_t) s1ap_send_handover_preparation_failure( + enb_ue_t *source_ue, S1ap_Cause_t *cause); + CORE_DECLARE(status_t) s1ap_send_handover_request( mme_ue_t *mme_ue, S1ap_HandoverRequiredIEs_t *required); -CORE_DECLARE(status_t) s1ap_send_handover_command(enb_ue_t *source_ue); + CORE_DECLARE(status_t) s1ap_send_handover_cancel_ack(enb_ue_t *source_ue); CORE_DECLARE(status_t) s1ap_send_mme_status_transfer(