diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index 4f2d165bc4..fb4ee12573 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -1467,12 +1467,17 @@ status_t mme_associate_ue_context(mme_ue_t *mme_ue, enb_ue_t *enb_ue) return CORE_OK; } -status_t mme_partial_associate_ue_context(mme_ue_t *mme_ue, enb_ue_t *enb_ue) +status_t mme_handover_associate_ue_context(mme_ue_t *mme_ue, enb_ue_t *target) { - d_assert(mme_ue, return CORE_ERROR, "Null param"); - d_assert(enb_ue, return CORE_ERROR, "Null param"); + enb_ue_t *source = NULL; - enb_ue->mme_ue = mme_ue; + d_assert(target, return CORE_ERROR, "Null param"); + d_assert(mme_ue, return CORE_ERROR, "Null param"); + source = mme_ue->enb_ue; + d_assert(source, return CORE_ERROR, "Null param"); + + target->mme_ue = mme_ue; + source->target = target; return CORE_OK; } diff --git a/src/mme/mme_context.h b/src/mme/mme_context.h index b64c02d31e..1b812d3b8c 100644 --- a/src/mme/mme_context.h +++ b/src/mme/mme_context.h @@ -133,11 +133,12 @@ struct _enb_ue_t { /* Handover Info */ S1ap_HandoverType_t handover_type; + enb_ue_t *target; - /* mme_ue_context */ + /* MME UE(NAS) */ mme_ue_t *mme_ue; - /* Connected enodeB */ + /* Connected eNB */ mme_enb_t *enb; }; @@ -285,6 +286,7 @@ struct _mme_ue_t { #define GTP_COUNTER_CHECK(__mME, __tYPE, __eXPR) \ do { \ d_assert((__mME), break,); \ + if ((__mME)->gtp_counter[__tYPE].request == 0) break; \ ((__mME)->gtp_counter[__tYPE].response)++; \ if (((__mME)->gtp_counter[__tYPE].request) == \ ((__mME)->gtp_counter[__tYPE].response)) \ @@ -461,8 +463,8 @@ CORE_DECLARE(status_t) mme_ue_set_imsi( mme_ue_t *mme_ue, c_int8_t *imsi_bcd); CORE_DECLARE(status_t) mme_associate_ue_context( mme_ue_t *mme_ue, enb_ue_t *enb_ue); -CORE_DECLARE(status_t) mme_partial_associate_ue_context( - mme_ue_t *mme_ue, enb_ue_t *enb_ue); +CORE_DECLARE(status_t) mme_handover_associate_ue_context( + mme_ue_t *mme_ue, enb_ue_t *target); CORE_DECLARE(hash_index_t *) mme_ue_first(); CORE_DECLARE(hash_index_t *) mme_ue_next(hash_index_t *hi); diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index 9b06a215e0..971b93b808 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -339,7 +339,6 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( gtp_create_indirect_data_forwarding_tunnel_response_t *rsp) { status_t rv; - enb_ue_t *enb_ue = NULL; mme_bearer_t *bearer = NULL; int i; @@ -350,9 +349,6 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( d_assert(mme_ue, return, "Null param"); d_assert(rsp, return, "Null param"); - enb_ue = mme_ue->enb_ue; - d_assert(enb_ue, return, "Null param"); - if (rsp->cause.presence == 0) { d_error("No Cause"); @@ -399,6 +395,6 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( d_assert(0, return, "Not Supported"); } - rv = s1ap_send_handover_command(enb_ue); + rv = s1ap_send_handover_command(mme_ue); d_assert(rv == CORE_OK,, "s1ap send error"); } diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index fb1af16f3c..d617ddc9a2 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -763,19 +763,17 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message) S1AP_STORE_DATA( &mme_ue->container, &ies->target_ToSource_TransparentContainer); - rv = mme_gtp_send_create_indirect_data_forwarding_tunnel_request(mme_ue); - d_assert(rv == CORE_OK, return, "gtp send failed"); - - -#if 0 - rv = mme_gtp_send_modify_bearer_request(bearer); - d_assert(rv == CORE_OK, return, "gtp send failed"); -#endif - -#if 0 - rv = s1ap_send_handover_request(mme_ue, ies); - d_assert(rv == CORE_OK,, "s1ap send error"); -#endif + if (i > 0) + { + rv = mme_gtp_send_create_indirect_data_forwarding_tunnel_request( + mme_ue); + d_assert(rv == CORE_OK, return, "gtp send failed"); + } + else + { + rv = s1ap_send_handover_command(mme_ue); + d_assert(rv == CORE_OK, return, "gtp send failed"); + } d_trace(3, "[S1AP] Handover Request Ack : " "UE[eNB-UE-S1AP-ID(%d)] --> eNB[%s:%d]\n", @@ -786,10 +784,39 @@ 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"); } void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message) { +// status_t rv; + char buf[INET_ADDRSTRLEN]; + + enb_ue_t *source = NULL, *target = NULL; + mme_ue_t *mme_ue = NULL; + + S1ap_ENBStatusTransferIEs_t *ies = NULL; + + d_assert(enb, return,); + + ies = &message->s1ap_ENBStatusTransferIEs; + d_assert(ies, return,); + + source = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID); + d_assert(source, return, + "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]", + ies->eNB_UE_S1AP_ID, + INET_NTOP(&enb->s1ap_sock->remote.sin_addr.s_addr, buf), + enb->enb_id); + d_assert(source->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return, + "Conflict MME-UE-S1AP-ID : %d != %d\n", + source->mme_ue_s1ap_id, ies->mme_ue_s1ap_id); + + mme_ue = source->mme_ue; + d_assert(mme_ue, return,); + target = source->target; + d_assert(target, return,); + } void s1ap_handle_handover_notification(mme_enb_t *enb, s1ap_message_t *message) diff --git a/src/mme/s1ap_path.c b/src/mme/s1ap_path.c index 43245b71cd..2192a97abf 100644 --- a/src/mme/s1ap_path.c +++ b/src/mme/s1ap_path.c @@ -464,7 +464,7 @@ status_t s1ap_send_handover_request( enb_ue = enb_ue_add(enb); d_assert(enb_ue, return CORE_ERROR,); - mme_partial_associate_ue_context(mme_ue, enb_ue); + mme_handover_associate_ue_context(mme_ue, enb_ue); rv = s1ap_build_handover_request(&s1apbuf, mme_ue, enb_ue, ies); d_assert(rv == CORE_OK && s1apbuf, @@ -476,13 +476,16 @@ status_t s1ap_send_handover_request( return rv; } -status_t s1ap_send_handover_command(enb_ue_t *enb_ue) +status_t s1ap_send_handover_command(mme_ue_t *mme_ue) { status_t rv; pkbuf_t *s1apbuf = NULL; mme_enb_t *enb = NULL; + enb_ue_t *enb_ue = NULL; + d_assert(mme_ue, return CORE_ERROR,); + enb_ue = mme_ue->enb_ue; d_assert(enb_ue, return CORE_ERROR,); enb = enb_ue->enb; d_assert(enb, return CORE_ERROR,); diff --git a/src/mme/s1ap_path.h b/src/mme/s1ap_path.h index 34fa5c401e..9c4ecbbbfe 100644 --- a/src/mme/s1ap_path.h +++ b/src/mme/s1ap_path.h @@ -31,7 +31,7 @@ CORE_DECLARE(status_t) s1ap_send_path_switch_failure(mme_enb_t *enb, 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 *enb_ue); +CORE_DECLARE(status_t) s1ap_send_handover_command(mme_ue_t *mme_ue); int _s1ap_recv_cb(net_sock_t *net_sock, void *data); diff --git a/test/handover_test.c b/test/handover_test.c index 0b021b520a..d7c10f2b75 100644 --- a/test/handover_test.c +++ b/test/handover_test.c @@ -582,6 +582,14 @@ static void handover_test2(abts_case *tc, void *data) ABTS_INT_NEQUAL(tc, 0, rc); pkbuf_free(recvbuf); + /* Send eNB Status Transfer */ + rv = tests1ap_build_enb_status_transfer(&sendbuf, 0); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock1, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(1000)); + /********** Remove Subscriber in Database */ doc = BCON_NEW("imsi", BCON_UTF8("001010123456815")); ABTS_PTR_NOTNULL(tc, doc); @@ -605,11 +613,8 @@ abts_suite *test_handover(abts_suite *suite) { suite = ADD_SUITE(suite) -#if 0 abts_run_test(suite, handover_test1, NULL); -#else abts_run_test(suite, handover_test2, NULL); -#endif return suite; }