From dbdd6bfdcfa4ee65a0032bd99ae90e7185f01b6e Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Tue, 13 Mar 2018 23:16:01 +0900 Subject: [PATCH] handover test --- src/mme/s1ap_build.c | 64 +++---- src/mme/s1ap_build.h | 12 +- src/mme/s1ap_handler.c | 368 ++++++++++++++++++++++++++----------- src/mme/s1ap_path.c | 33 ++-- src/mme/s1ap_path.h | 16 +- src/mme/s1ap_sm.c | 15 +- test/basic/handover_test.c | 9 +- 7 files changed, 357 insertions(+), 160 deletions(-) diff --git a/src/mme/s1ap_build.c b/src/mme/s1ap_build.c index 7b337440f..e83578d32 100644 --- a/src/mme/s1ap_build.c +++ b/src/mme/s1ap_build.c @@ -1451,27 +1451,20 @@ status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue) S1AP_E_RABDataForwardingItemIEs_t *item = NULL; S1AP_E_RABDataForwardingItem_t *e_rab = NULL; - if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer) || - MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) - { - item = core_calloc( - 1, sizeof(S1AP_E_RABDataForwardingItemIEs_t)); - ASN_SEQUENCE_ADD(&E_RABSubjecttoDataForwardingList->list, item); + item = core_calloc( + 1, sizeof(S1AP_E_RABDataForwardingItemIEs_t)); + ASN_SEQUENCE_ADD(&E_RABSubjecttoDataForwardingList->list, item); - item->id = S1AP_ProtocolIE_ID_id_E_RABDataForwardingItem; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABDataForwardingItemIEs__value_PR_E_RABDataForwardingItem; + item->id = S1AP_ProtocolIE_ID_id_E_RABDataForwardingItem; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABDataForwardingItemIEs__value_PR_E_RABDataForwardingItem; - e_rab = &item->value.choice.E_RABDataForwardingItem; + e_rab = &item->value.choice.E_RABDataForwardingItem; - e_rab = (S1AP_E_RABDataForwardingItem_t *) - core_calloc(1, sizeof(S1AP_E_RABDataForwardingItem_t)); - e_rab->e_RAB_ID = bearer->ebi; - } + e_rab->e_RAB_ID = bearer->ebi; if (MME_HAVE_SGW_DL_INDIRECT_TUNNEL(bearer)) { - d_assert(e_rab, return CORE_ERROR,); e_rab->dL_transportLayerAddress = (S1AP_TransportLayerAddress_t *) core_calloc(1, sizeof(S1AP_TransportLayerAddress_t)); @@ -1486,9 +1479,8 @@ status_t s1ap_build_handover_command(pkbuf_t **s1apbuf, enb_ue_t *source_ue) d_trace(5, " SGW-DL-TEID[%d]\n", bearer->sgw_dl_teid); } - if (e_rab && MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) + if (MME_HAVE_SGW_UL_INDIRECT_TUNNEL(bearer)) { - d_assert(e_rab, return CORE_ERROR,); e_rab->uL_TransportLayerAddress = (S1AP_TransportLayerAddress_t *) core_calloc(1, sizeof(S1AP_TransportLayerAddress_t)); @@ -1611,7 +1603,13 @@ status_t s1ap_build_handover_preparation_failure( status_t s1ap_build_handover_request( pkbuf_t **s1apbuf, mme_ue_t *mme_ue, enb_ue_t *target_ue, - S1AP_HandoverRequiredIEs_t *required) + S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id, + S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id, + S1AP_HandoverType_t *handovertype, + S1AP_Cause_t *cause, + S1AP_TargetID_t *targetid, + S1AP_Source_ToTarget_TransparentContainer_t + *source_totarget_transparentContainer) { status_t rv; @@ -1634,9 +1632,12 @@ status_t s1ap_build_handover_request( mme_bearer_t *bearer = NULL; s6a_subscription_data_t *subscription_data = NULL; + d_assert(handovertype, return CORE_ERROR,); + d_assert(cause, return CORE_ERROR,); + d_assert(source_totarget_transparentContainer, return CORE_ERROR,); + d_assert(target_ue, return CORE_ERROR, "Null param"); d_assert(mme_ue, return CORE_ERROR, "Null param"); - d_assert(required, return CORE_ERROR, "Null param"); subscription_data = &mme_ue->subscription_data; d_assert(subscription_data, return CORE_ERROR, "Null param"); @@ -1733,10 +1734,9 @@ status_t s1ap_build_handover_request( SecurityContext = &ie->value.choice.SecurityContext; *MME_UE_S1AP_ID = target_ue->mme_ue_s1ap_id; - *HandoverType = required->value.choice.HandoverType; - Cause->present = required->value.choice.Cause.present; - Cause->choice.radioNetwork = - required->value.choice.Cause.choice.radioNetwork; + *HandoverType = *handovertype; + Cause->present = cause->present; + Cause->choice.radioNetwork = cause->choice.radioNetwork; asn_uint642INTEGER( &UEAggregateMaximumBitrate->uEaggregateMaximumBitRateUL, @@ -1815,8 +1815,8 @@ status_t s1ap_build_handover_request( } s1ap_buffer_to_OCTET_STRING( - required->value.choice.Source_ToTarget_TransparentContainer.buf, - required->value.choice.Source_ToTarget_TransparentContainer.size, + source_totarget_transparentContainer->buf, + source_totarget_transparentContainer->size, Source_ToTarget_TransparentContainer); UESecurityCapabilities->encryptionAlgorithms.size = 2; @@ -1925,10 +1925,12 @@ status_t s1ap_build_handover_cancel_ack(pkbuf_t **s1apbuf, enb_ue_t *source_ue) } status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, - enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *enb_ies) + enb_ue_t *target_ue, + S1AP_ENB_StatusTransfer_TransparentContainer_t + *enb_statustransfer_transparentContainer) { status_t rv; - int i; +// int i; S1AP_S1AP_PDU_t pdu; S1AP_InitiatingMessage_t *initiatingMessage = NULL; @@ -1943,7 +1945,7 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, #endif d_assert(target_ue, return CORE_ERROR,); - d_assert(enb_ies, return CORE_ERROR,); + d_assert(enb_statustransfer_transparentContainer, return CORE_ERROR,); d_trace(3, "[MME] MME status transfer\n"); @@ -1978,6 +1980,7 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID; +#if 0 ie = core_calloc(1, sizeof(S1AP_MMEStatusTransferIEs_t)); ASN_SEQUENCE_ADD(&MMEStatusTransfer->protocolIEs, ie); @@ -1986,7 +1989,6 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, ie->value.present = S1AP_MMEStatusTransferIEs__value_PR_ENB_StatusTransfer_TransparentContainer; -#if 0 ENB_StatusTransfer_TransparentContainer = &ie->value.choice.ENB_StatusTransfer_TransparentContainer; #endif @@ -1997,11 +1999,11 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, d_trace(5, " Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id); +#if 0 for (i = 0; i < enb_ies->value.choice. ENB_StatusTransfer_TransparentContainer. bearers_SubjectToStatusTransferList.list.count; i++) { -#if 0 S1AP_Bearers_SubjectToStatusTransferList_IEs_t *mme_ie = NULL; S1AP_Bearers_SubjectToStatusTransferList_t *mme_list = NULL; S1AP_IE_t *enb_ie = NULL, *mme_ie = NULL; @@ -2017,8 +2019,8 @@ status_t s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, ASN_SEQUENCE_ADD(&mme_ies-> eNB_StatusTransfer_TransparentContainer. bearers_SubjectToStatusTransferList, mme_ie); -#endif } +#endif rv = s1ap_encode_pdu(s1apbuf, &pdu); s1ap_free_pdu(&pdu); diff --git a/src/mme/s1ap_build.h b/src/mme/s1ap_build.h index 4621909dc..93d03b2fa 100644 --- a/src/mme/s1ap_build.h +++ b/src/mme/s1ap_build.h @@ -38,13 +38,21 @@ CORE_DECLARE(status_t) s1ap_build_handover_preparation_failure( 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); + S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id, + S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id, + S1AP_HandoverType_t *handovertype, + S1AP_Cause_t *cause, + S1AP_TargetID_t *targetid, + S1AP_Source_ToTarget_TransparentContainer_t + *source_totarget_transparentContainer); CORE_DECLARE(status_t) s1ap_build_handover_cancel_ack( pkbuf_t **s1apbuf, enb_ue_t *source_ue); CORE_DECLARE(status_t) s1ap_build_mme_status_transfer(pkbuf_t **s1apbuf, - enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *enb_ies); + enb_ue_t *target_ue, + S1AP_ENB_StatusTransfer_TransparentContainer_t + *enb_statustransfer_transparentContainer); CORE_DECLARE(status_t) s1ap_build_error_indication( pkbuf_t **s1apbuf, diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index 03d86f092..9ebb8a80c 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -1267,34 +1267,165 @@ void s1ap_handle_path_switch_request( enb_ue_switch_to_enb(enb_ue, enb); } -#if 0 +void s1ap_handle_enb_configuration_transfer( + mme_enb_t *enb, s1ap_message_t *message, pkbuf_t *pkbuf) +{ + status_t rv; + char buf[CORE_ADDRSTRLEN]; + int i; + + S1AP_InitiatingMessage_t *initiatingMessage = NULL; + S1AP_ENBConfigurationTransfer_t *ENBConfigurationTransfer = NULL; + + S1AP_ENBConfigurationTransferIEs_t *ie = NULL; + S1AP_SONConfigurationTransfer_t *SONConfigurationTransfer = NULL; + + d_assert(enb, return,); + d_assert(enb->sock, return,); + + d_assert(message, return,); + initiatingMessage = message->choice.initiatingMessage; + d_assert(initiatingMessage, return,); + ENBConfigurationTransfer = + &initiatingMessage->value.choice.ENBConfigurationTransfer; + d_assert(ENBConfigurationTransfer, return,); + + d_trace(3, "[MME] ENB configuration transfer\n"); + for (i = 0; i < ENBConfigurationTransfer->protocolIEs.list.count; i++) + { + ie = ENBConfigurationTransfer->protocolIEs.list.array[i]; + switch(ie->id) + { + case S1AP_ProtocolIE_ID_id_SONConfigurationTransferECT: + SONConfigurationTransfer = + &ie->value.choice.SONConfigurationTransfer; + break; + default: + break; + } + } + + d_trace(5, " IP[%s] ENB_ID[%d]\n", + CORE_ADDR(enb->addr, buf), enb->enb_id); + + if (SONConfigurationTransfer) + { + S1AP_SONConfigurationTransfer_t *transfer = SONConfigurationTransfer; + mme_enb_t *target_enb = NULL; + c_uint32_t source_enb_id, target_enb_id; + c_uint16_t source_tac, target_tac; + + d_assert(transfer, return,); + + s1ap_ENB_ID_to_uint32( + &transfer->sourceeNB_ID.global_ENB_ID.eNB_ID, + &source_enb_id); + s1ap_ENB_ID_to_uint32( + &transfer->targeteNB_ID.global_ENB_ID.eNB_ID, + &target_enb_id); + + memcpy(&source_tac, transfer->sourceeNB_ID.selected_TAI.tAC.buf, + sizeof(source_tac)); + source_tac = ntohs(source_tac); + memcpy(&target_tac, transfer->targeteNB_ID.selected_TAI.tAC.buf, + sizeof(target_tac)); + target_tac = ntohs(target_tac); + + d_trace(5, " Source : ENB_ID[%s:%d], TAC[%d]\n", + transfer->sourceeNB_ID.global_ENB_ID.eNB_ID.present == + S1AP_ENB_ID_PR_homeENB_ID ? "Home" : + transfer->sourceeNB_ID.global_ENB_ID.eNB_ID.present == + S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others", + source_enb_id, source_tac); + d_trace(5, " Target : ENB_ID[%s:%d], TAC[%d]\n", + transfer->targeteNB_ID.global_ENB_ID.eNB_ID.present == + S1AP_ENB_ID_PR_homeENB_ID ? "Home" : + transfer->targeteNB_ID.global_ENB_ID.eNB_ID.present == + S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others", + target_enb_id, target_tac); + + target_enb = mme_enb_find_by_enb_id(target_enb_id); + d_assert(target_enb, return, + "Cannot find target eNB = %d", target_enb_id); + + rv = s1ap_send_mme_configuration_transfer(target_enb, pkbuf); + d_assert(rv == CORE_OK,,); + } +} + void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message) { status_t rv; char buf[CORE_ADDRSTRLEN]; + int i; + + S1AP_InitiatingMessage_t *initiatingMessage = NULL; + S1AP_HandoverRequired_t *HandoverRequired = NULL; + + S1AP_HandoverRequiredIEs_t *ie = NULL; + S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL; + S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL; + S1AP_HandoverType_t *HandoverType = NULL; + S1AP_Cause_t *Cause = NULL; + S1AP_TargetID_t *TargetID = NULL; + S1AP_Source_ToTarget_TransparentContainer_t + *Source_ToTarget_TransparentContainer = NULL; + + d_assert(enb, return,); + d_assert(enb->sock, return,); + + d_assert(message, return,); + initiatingMessage = message->choice.initiatingMessage; + d_assert(initiatingMessage, return,); + HandoverRequired = &initiatingMessage->value.choice.HandoverRequired; + d_assert(HandoverRequired, return,); enb_ue_t *source_ue = NULL; mme_ue_t *mme_ue = NULL; - S1AP_HandoverRequiredIEs_t *ies = NULL; - - d_assert(enb, return,); - - ies = &message->s1ap_HandoverRequiredIEs; - d_assert(ies, return,); - d_trace(3, "[MME] Handover required\n"); + for (i = 0; i < HandoverRequired->protocolIEs.list.count; i++) + { + ie = HandoverRequired->protocolIEs.list.array[i]; + switch(ie->id) + { + case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID: + ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID; + break; + case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID: + MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID; + break; + case S1AP_ProtocolIE_ID_id_HandoverType: + HandoverType = &ie->value.choice.HandoverType; + break; + case S1AP_ProtocolIE_ID_id_Cause: + Cause = &ie->value.choice.Cause; + break; + case S1AP_ProtocolIE_ID_id_TargetID: + TargetID = &ie->value.choice.TargetID; + break; + case S1AP_ProtocolIE_ID_id_Source_ToTarget_TransparentContainer: + Source_ToTarget_TransparentContainer = + &ie->value.choice.Source_ToTarget_TransparentContainer; + break; + default: + break; + } + } + d_trace(5, " IP[%s] ENB_ID[%d]\n", CORE_ADDR(enb->addr, buf), enb->enb_id); - source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID); + d_assert(ENB_UE_S1AP_ID, return,); + d_assert(MME_UE_S1AP_ID, return,); + source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID); d_assert(source_ue, return, "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]", - ies->eNB_UE_S1AP_ID, + *ENB_UE_S1AP_ID, CORE_ADDR(enb->addr, buf), enb->enb_id); - d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return, + d_assert(source_ue->mme_ue_s1ap_id == *MME_UE_S1AP_ID, return, "Conflict MME-UE-S1AP-ID : %d != %d\n", - source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id); + source_ue->mme_ue_s1ap_id, *MME_UE_S1AP_ID); d_trace(5, " Source : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", source_ue->enb_ue_s1ap_id, source_ue->mme_ue_s1ap_id); @@ -1309,15 +1440,21 @@ void s1ap_handle_handover_required(mme_enb_t *enb, s1ap_message_t *message) } else { - rv = s1ap_send_handover_preparation_failure(source_ue, &ies->cause); + d_assert(Cause, return,); + + rv = s1ap_send_handover_preparation_failure(source_ue, Cause); d_assert(rv == CORE_OK, return, "s1ap send error"); return; } - source_ue->handover_type = ies->handoverType; + d_assert(HandoverType, return,); + source_ue->handover_type = *HandoverType; - rv = s1ap_send_handover_request(mme_ue, ies); + rv = s1ap_send_handover_request(mme_ue, + ENB_UE_S1AP_ID, MME_UE_S1AP_ID, + HandoverType, Cause, TargetID, + Source_ToTarget_TransparentContainer); d_assert(rv == CORE_OK,, "s1ap send error"); } @@ -1327,28 +1464,68 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message) char buf[CORE_ADDRSTRLEN]; int i; + S1AP_SuccessfulOutcome_t *successfulOutcome = NULL; + S1AP_HandoverRequestAcknowledge_t *HandoverRequestAcknowledge = NULL; + + S1AP_HandoverRequestAcknowledgeIEs_t *ie = NULL; + S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL; + S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL; + S1AP_E_RABAdmittedList_t *E_RABAdmittedList = NULL; + S1AP_Target_ToSource_TransparentContainer_t + *Target_ToSource_TransparentContainer = NULL; + enb_ue_t *source_ue = NULL; enb_ue_t *target_ue = NULL; mme_ue_t *mme_ue = NULL; - S1AP_HandoverRequestAcknowledgeIEs_t *ies = NULL; - d_assert(enb, return,); + d_assert(enb->sock, return,); - ies = &message->s1ap_HandoverRequestAcknowledgeIEs; - d_assert(ies, return,); + d_assert(message, return,); + successfulOutcome = message->choice.successfulOutcome; + d_assert(successfulOutcome, return,); + HandoverRequestAcknowledge = + &successfulOutcome->value.choice.HandoverRequestAcknowledge; + d_assert(HandoverRequestAcknowledge, return,); d_trace(3, "[MME] Handover request acknowledge\n"); + for (i = 0; i < HandoverRequestAcknowledge->protocolIEs.list.count; i++) + { + ie = HandoverRequestAcknowledge->protocolIEs.list.array[i]; + switch(ie->id) + { + case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID: + MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID; + break; + case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID: + ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID; + break; + case S1AP_ProtocolIE_ID_id_E_RABAdmittedList: + E_RABAdmittedList = &ie->value.choice.E_RABAdmittedList; + break; + case S1AP_ProtocolIE_ID_id_Target_ToSource_TransparentContainer: + Target_ToSource_TransparentContainer = + &ie->value.choice.Target_ToSource_TransparentContainer; + break; + default: + break; + } + } d_trace(5, " IP[%s] ENB_ID[%d]\n", CORE_ADDR(enb->addr, buf), enb->enb_id); - target_ue = enb_ue_find_by_mme_ue_s1ap_id(ies->mme_ue_s1ap_id); + d_assert(MME_UE_S1AP_ID, return,); + d_assert(ENB_UE_S1AP_ID, return,); + d_assert(E_RABAdmittedList, return,); + d_assert(Target_ToSource_TransparentContainer, return,); + + target_ue = enb_ue_find_by_mme_ue_s1ap_id(*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, + *MME_UE_S1AP_ID, CORE_ADDR(enb->addr, buf), enb->enb_id); - target_ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID; + target_ue->enb_ue_s1ap_id = *ENB_UE_S1AP_ID; source_ue = target_ue->source_ue; d_assert(source_ue, return,); @@ -1360,17 +1537,21 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message) d_trace(5, " Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id); - for (i = 0; i < ies->e_RABAdmittedList.s1ap_E_RABAdmittedItem.count; i++) + for (i = 0; i < E_RABAdmittedList->list.count; i++) { - mme_bearer_t *bearer = NULL; + S1AP_E_RABAdmittedItemIEs_t *item = NULL; S1AP_E_RABAdmittedItem_t *e_rab = NULL; - e_rab = (S1AP_E_RABAdmittedItem_t *)ies->e_RABAdmittedList. - s1ap_E_RABAdmittedItem.array[i]; - d_assert(e_rab, return, "Null param"); + mme_bearer_t *bearer = NULL; + + item = (S1AP_E_RABAdmittedItemIEs_t *)E_RABAdmittedList->list.array[i]; + d_assert(item, return,); + + e_rab = &item->value.choice.E_RABAdmittedItem; + d_assert(e_rab, return,); bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID); - d_assert(bearer, return, "Null param"); + d_assert(bearer, return,); memcpy(&bearer->target_s1u_teid, e_rab->gTP_TEID.buf, sizeof(bearer->target_s1u_teid)); @@ -1391,21 +1572,21 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message) d_assert(rv == CORE_OK, return,); } - if (e_rab->uL_S1AP_TransportLayerAddress && e_rab->uL_S1AP_GTP_TEID) + if (e_rab->uL_TransportLayerAddress && e_rab->uL_GTP_TEID) { - d_assert(e_rab->uL_S1AP_GTP_TEID->buf, return,); - d_assert(e_rab->uL_S1AP_TransportLayerAddress->buf, return,); - memcpy(&bearer->enb_ul_teid, e_rab->uL_S1AP_GTP_TEID->buf, + d_assert(e_rab->uL_GTP_TEID->buf, return,); + d_assert(e_rab->uL_TransportLayerAddress->buf, return,); + memcpy(&bearer->enb_ul_teid, e_rab->uL_GTP_TEID->buf, sizeof(bearer->enb_ul_teid)); bearer->enb_ul_teid = ntohl(bearer->enb_ul_teid); rv = s1ap_BIT_STRING_to_ip( - e_rab->uL_S1AP_TransportLayerAddress, &bearer->enb_ul_ip); + e_rab->uL_TransportLayerAddress, &bearer->enb_ul_ip); d_assert(rv == CORE_OK, return,); } } S1AP_STORE_DATA( - &mme_ue->container, &ies->target_ToSource_TransparentContainer); + &mme_ue->container, Target_ToSource_TransparentContainer); if (mme_ue_have_indirect_tunnel(mme_ue) == 1) { @@ -1420,6 +1601,7 @@ void s1ap_handle_handover_request_ack(mme_enb_t *enb, s1ap_message_t *message) } } +#if 0 void s1ap_handle_handover_failure(mme_enb_t *enb, s1ap_message_t *message) { status_t rv; @@ -1512,33 +1694,69 @@ void s1ap_handle_handover_cancel(mme_enb_t *enb, s1ap_message_t *message) source_ue->enb_ue_s1ap_id, CORE_ADDR(enb->addr, buf), enb->enb_id); } +#endif void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message) { status_t rv; char buf[CORE_ADDRSTRLEN]; + int i; + + S1AP_InitiatingMessage_t *initiatingMessage = NULL; + S1AP_ENBStatusTransfer_t *ENBStatusTransfer = NULL; + + S1AP_ENBStatusTransferIEs_t *ie = NULL; + S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL; + S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL; + S1AP_ENB_StatusTransfer_TransparentContainer_t + *ENB_StatusTransfer_TransparentContainer = NULL; enb_ue_t *source_ue = NULL, *target_ue = NULL; - S1AP_ENBStatusTransferIEs_t *ies = NULL; - d_assert(enb, return,); + d_assert(enb->sock, return,); - ies = &message->s1ap_ENBStatusTransferIEs; - d_assert(ies, return,); + d_assert(message, return,); + initiatingMessage = message->choice.initiatingMessage; + d_assert(initiatingMessage, return,); + ENBStatusTransfer = &initiatingMessage->value.choice.ENBStatusTransfer; + d_assert(ENBStatusTransfer, return,); d_trace(3, "[MME] ENB status transfer\n"); + for (i = 0; i < ENBStatusTransfer->protocolIEs.list.count; i++) + { + ie = ENBStatusTransfer->protocolIEs.list.array[i]; + switch(ie->id) + { + case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID: + MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID; + break; + case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID: + ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID; + break; + case S1AP_ProtocolIE_ID_id_eNB_StatusTransfer_TransparentContainer: + ENB_StatusTransfer_TransparentContainer = + &ie->value.choice.ENB_StatusTransfer_TransparentContainer; + break; + default: + break; + } + } d_trace(5, " IP[%s] ENB_ID[%d]\n", CORE_ADDR(enb->addr, buf), enb->enb_id); - source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, ies->eNB_UE_S1AP_ID); + d_assert(MME_UE_S1AP_ID, return,); + d_assert(ENB_UE_S1AP_ID, return,); + d_assert(ENB_StatusTransfer_TransparentContainer, return,); + + source_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID); d_assert(source_ue, return, "Cannot find UE for eNB-UE-S1AP-ID[%d] and eNB[%s:%d]", - ies->eNB_UE_S1AP_ID, + *ENB_UE_S1AP_ID, CORE_ADDR(enb->addr, buf), enb->enb_id); - d_assert(source_ue->mme_ue_s1ap_id == ies->mme_ue_s1ap_id, return, + d_assert(source_ue->mme_ue_s1ap_id == *MME_UE_S1AP_ID, return, "Conflict MME-UE-S1AP-ID : %d != %d\n", - source_ue->mme_ue_s1ap_id, ies->mme_ue_s1ap_id); + source_ue->mme_ue_s1ap_id, *MME_UE_S1AP_ID); target_ue = source_ue->target_ue; d_assert(target_ue, return,); @@ -1548,72 +1766,12 @@ void s1ap_handle_enb_status_transfer(mme_enb_t *enb, s1ap_message_t *message) d_trace(5, " Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id); - rv = s1ap_send_mme_status_transfer(target_ue, ies); + rv = s1ap_send_mme_status_transfer(target_ue, + ENB_StatusTransfer_TransparentContainer); d_assert(rv == CORE_OK,,); } -void s1ap_handle_enb_configuration_transfer( - mme_enb_t *enb, s1ap_message_t *message, pkbuf_t *pkbuf) -{ - status_t rv; - char buf[CORE_ADDRSTRLEN]; - - S1AP_ENBConfigurationTransferIEs_t *ies = NULL; - - d_assert(enb, return,); - - ies = &message->s1ap_ENBConfigurationTransferIEs; - d_assert(ies, return,); - - d_trace(3, "[MME] ENB configuration transfer\n"); - d_trace(5, " IP[%s] ENB_ID[%d]\n", - CORE_ADDR(enb->addr, buf), enb->enb_id); - - if (ies->presenceMask & - S1AP_ENBCONFIGURATIONTRANSFERIES_SONCONFIGURATIONTRANSFERECT_PRESENT) - { - S1AP_SONConfigurationTransfer_t *transfer = - &ies->sonConfigurationTransferECT; - mme_enb_t *target_enb = NULL; - c_uint32_t source_enb_id, target_enb_id; - c_uint16_t source_tac, target_tac; - - s1ap_ENB_ID_to_uint32( - &transfer->sourceeNB_ID.global_S1AP_ENB_ID.eNB_ID, - &source_enb_id); - s1ap_ENB_ID_to_uint32( - &transfer->targeteNB_ID.global_S1AP_ENB_ID.eNB_ID, - &target_enb_id); - - memcpy(&source_tac, transfer->sourceeNB_ID.selected_S1AP_TAI.tAC.buf, - sizeof(source_tac)); - source_tac = ntohs(source_tac); - memcpy(&target_tac, transfer->targeteNB_ID.selected_S1AP_TAI.tAC.buf, - sizeof(target_tac)); - target_tac = ntohs(target_tac); - - d_trace(5, " Source : ENB_ID[%s:%d], TAC[%d]\n", - transfer->sourceeNB_ID.global_S1AP_ENB_ID.eNB_ID.present == - S1AP_ENB_ID_PR_homeENB_ID ? "Home" : - transfer->sourceeNB_ID.global_S1AP_ENB_ID.eNB_ID.present == - S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others", - source_enb_id, source_tac); - d_trace(5, " Target : ENB_ID[%s:%d], TAC[%d]\n", - transfer->targeteNB_ID.global_S1AP_ENB_ID.eNB_ID.present == - S1AP_ENB_ID_PR_homeENB_ID ? "Home" : - transfer->targeteNB_ID.global_S1AP_ENB_ID.eNB_ID.present == - S1AP_ENB_ID_PR_macroENB_ID ? "Macro" : "Others", - target_enb_id, target_tac); - - target_enb = mme_enb_find_by_enb_id(target_enb_id); - d_assert(target_enb, return, - "Cannot find target eNB = %d", target_enb_id); - - rv = s1ap_send_mme_configuration_transfer(target_enb, pkbuf); - d_assert(rv == CORE_OK,,); - } -} - +#if 0 void s1ap_handle_handover_notification(mme_enb_t *enb, s1ap_message_t *message) { status_t rv; diff --git a/src/mme/s1ap_path.c b/src/mme/s1ap_path.c index 6e0a9ded0..49e6b5978 100644 --- a/src/mme/s1ap_path.c +++ b/src/mme/s1ap_path.c @@ -371,9 +371,15 @@ status_t s1ap_send_handover_cancel_ack(enb_ue_t *source_ue) status_t s1ap_send_handover_request( - mme_ue_t *mme_ue, S1AP_HandoverRequiredIEs_t *ies) + mme_ue_t *mme_ue, + S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id, + S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id, + S1AP_HandoverType_t *handovertype, + S1AP_Cause_t *cause, + S1AP_TargetID_t *targetid, + S1AP_Source_ToTarget_TransparentContainer_t + *source_totarget_transparentContainer) { -#if 0 status_t rv; pkbuf_t *s1apbuf = NULL; S1AP_TargetID_t *targetID = NULL; @@ -387,17 +393,15 @@ status_t s1ap_send_handover_request( d_assert(mme_ue, return CORE_ERROR,); source_ue = mme_ue->enb_ue; d_assert(source_ue, return CORE_ERROR,); - d_assert(ies, return CORE_ERROR,); - targetID = &ies->targetID; - d_assert(targetID, return CORE_ERROR,); + d_assert(targetid, return CORE_ERROR,); - switch(targetID->present) + switch(targetid->present) { case S1AP_TargetID_PR_targeteNB_ID: { s1ap_ENB_ID_to_uint32( - &targetID->choice.targeteNB_ID.global_S1AP_ENB_ID.eNB_ID, + &targetid->choice.targeteNB_ID->global_ENB_ID.eNB_ID, &enb_id); break; } @@ -426,20 +430,22 @@ status_t s1ap_send_handover_request( rv = source_ue_associate_target_ue(source_ue, target_ue); d_assert(rv == CORE_OK, return CORE_ERROR,); - rv = s1ap_build_handover_request(&s1apbuf, mme_ue, target_ue, ies); + rv = s1ap_build_handover_request(&s1apbuf, mme_ue, target_ue, + enb_ue_s1ap_id, mme_ue_s1ap_id, + handovertype, cause, targetid, + source_totarget_transparentContainer); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); rv = s1ap_send_to_enb(target_enb, s1apbuf); d_assert(rv == CORE_OK,, "s1ap send error"); return rv; -#else - return CORE_OK; -#endif } status_t s1ap_send_mme_status_transfer( - enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *ies) + enb_ue_t *target_ue, + S1AP_ENB_StatusTransfer_TransparentContainer_t + *enb_statustransfer_transparentContainer) { status_t rv; pkbuf_t *s1apbuf = NULL; @@ -450,7 +456,8 @@ status_t s1ap_send_mme_status_transfer( enb = target_ue->enb; d_assert(enb, return CORE_ERROR,); - rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue, ies); + rv = s1ap_build_mme_status_transfer(&s1apbuf, target_ue, + enb_statustransfer_transparentContainer); d_assert(rv == CORE_OK && s1apbuf, return CORE_ERROR, "s1ap build error"); rv = s1ap_send_to_enb(enb, s1apbuf); diff --git a/src/mme/s1ap_path.h b/src/mme/s1ap_path.h index 900a7bcde..be32310b3 100644 --- a/src/mme/s1ap_path.h +++ b/src/mme/s1ap_path.h @@ -44,17 +44,29 @@ 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_PR group, long cause); +CORE_DECLARE(status_t) s1ap_send_mme_configuration_transfer( + mme_enb_t *target_enb, pkbuf_t *pkbuf); + 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); + mme_ue_t *mme_ue, + S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id, + S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id, + S1AP_HandoverType_t *handovertype, + S1AP_Cause_t *cause, + S1AP_TargetID_t *targetid, + S1AP_Source_ToTarget_TransparentContainer_t + *source_totarget_transparentContainer); CORE_DECLARE(status_t) s1ap_send_handover_cancel_ack(enb_ue_t *source_ue); CORE_DECLARE(status_t) s1ap_send_mme_status_transfer( - enb_ue_t *target_ue, S1AP_ENBStatusTransferIEs_t *ies); + enb_ue_t *target_ue, + S1AP_ENB_StatusTransfer_TransparentContainer_t + *enb_statustransfer_transparentContainer); CORE_DECLARE(status_t) s1ap_send_error_indication( mme_enb_t *enb, S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id, diff --git a/src/mme/s1ap_sm.c b/src/mme/s1ap_sm.c index 3fd8fda3d..6f6abcbd0 100644 --- a/src/mme/s1ap_sm.c +++ b/src/mme/s1ap_sm.c @@ -96,22 +96,33 @@ void s1ap_state_operational(fsm_t *s, event_t *e) s1ap_handle_path_switch_request(enb, pdu); break; } -#if 0 + case S1AP_ProcedureCode_id_eNBConfigurationTransfer: + { + pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e); + d_assert(pkbuf, break, "Null param"); + + s1ap_handle_enb_configuration_transfer( + enb, pdu, pkbuf); + break; + } case S1AP_ProcedureCode_id_HandoverPreparation: { s1ap_handle_handover_required(enb, pdu); break; } +#if 0 case S1AP_ProcedureCode_id_HandoverCancel: { s1ap_handle_handover_cancel(enb, pdu); break; } +#endif case S1AP_ProcedureCode_id_eNBStatusTransfer: { s1ap_handle_enb_status_transfer(enb, pdu); break; } +#if 0 case S1AP_ProcedureCode_id_HandoverNotification: { s1ap_handle_handover_notification(enb, pdu); @@ -162,13 +173,11 @@ void s1ap_state_operational(fsm_t *s, event_t *e) enb, pdu); break; } -#if 0 case S1AP_ProcedureCode_id_HandoverResourceAllocation: { s1ap_handle_handover_request_ack(enb, pdu); break; } -#endif default: { d_warn("Not implemented(choice:%d, proc:%d)", diff --git a/test/basic/handover_test.c b/test/basic/handover_test.c index e447abd4c..8cd50df84 100644 --- a/test/basic/handover_test.c +++ b/test/basic/handover_test.c @@ -343,7 +343,6 @@ static void handover_test1(abts_case *tc, void *data) core_sleep(time_from_msec(300)); } -#if 0 static void handover_test2(abts_case *tc, void *data) { status_t rv; @@ -656,6 +655,11 @@ static void handover_test2(abts_case *tc, void *data) rv = tests1ap_enb_send(sock1, sendbuf); ABTS_INT_EQUAL(tc, CORE_OK, rv); +#if 1 + core_sleep(time_from_msec(1000)); + goto out; +#endif + /* Receive MME Status Transfer */ recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); rv = tests1ap_enb_read(sock2, recvbuf); @@ -851,16 +855,13 @@ out: core_sleep(time_from_msec(300)); } -#endif abts_suite *test_handover(abts_suite *suite) { suite = ADD_SUITE(suite) abts_run_test(suite, handover_test1, NULL); -#if 0 abts_run_test(suite, handover_test2, NULL); -#endif return suite; }