diff --git a/lib/pfcp/xact.h b/lib/pfcp/xact.h index aaf77ef61..03ce79bc7 100644 --- a/lib/pfcp/xact.h +++ b/lib/pfcp/xact.h @@ -80,6 +80,7 @@ typedef struct ogs_pfcp_xact_s { #define OGS_PFCP_MODIFY_DEACTIVATE ((uint64_t)1<<9) #define OGS_PFCP_MODIFY_END_MARKER ((uint64_t)1<<10) #define OGS_PFCP_MODIFY_ERROR_INDICATION ((uint64_t)1<<11) +#define OGS_PFCP_MODIFY_PATH_SWITCH ((uint64_t)1<<12) uint64_t modify_flags; #define OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED 1 diff --git a/src/amf/ngap-build.c b/src/amf/ngap-build.c index f8a6d504f..c7a274810 100644 --- a/src/amf/ngap-build.c +++ b/src/amf/ngap-build.c @@ -1287,9 +1287,15 @@ ogs_pkbuf_t *ngap_build_amf_configuration_transfer( return ogs_ngap_encode(&pdu); } +#endif -ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue) +ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue, ogs_pkbuf_t *n2smbuf) { + int i, j; + + ran_ue_t *ran_ue = NULL; + amf_sess_t *sess = NULL; + NGAP_NGAP_PDU_t pdu; NGAP_SuccessfulOutcome_t *successfulOutcome = NULL; NGAP_PathSwitchRequestAcknowledge_t *PathSwitchRequestAcknowledge = NULL; @@ -1298,19 +1304,16 @@ ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue) NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_SecurityContext_t *SecurityContext = NULL; - - ran_ue_t *ran_ue = NULL; + NGAP_PDUSessionResourceSwitchedList_t *PDUSessionResourceSwitchedList; + NGAP_AllowedNSSAI_t *AllowedNSSAI = NULL; ogs_assert(amf_ue); ran_ue = ran_ue_cycle(amf_ue->ran_ue); ogs_assert(ran_ue); - ogs_debug("Path switch acknowledge"); - memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome = - CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome = CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t)); successfulOutcome = pdu.choice.successfulOutcome; successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PathSwitchRequest; @@ -1351,6 +1354,13 @@ ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue) SecurityContext = &ie->value.choice.SecurityContext; + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSwitchedList; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_PDUSessionResourceSwitchedList; + ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]", ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id); @@ -1358,88 +1368,86 @@ ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue) *RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id; SecurityContext->nextHopChainingCount = amf_ue->nhcc; - SecurityContext->nextHopParameter.size = OGS_SHA256_DIGEST_SIZE; - SecurityContext->nextHopParameter.buf = - CALLOC(SecurityContext->nextHopParameter.size, - sizeof(uint8_t)); - SecurityContext->nextHopParameter.bits_unused = 0; - memcpy(SecurityContext->nextHopParameter.buf, - amf_ue->nh, SecurityContext->nextHopParameter.size); - - return ogs_ngap_encode(&pdu); -} - -ogs_pkbuf_t *ngap_build_path_switch_failure( - uint32_t ran_ue_ngap_id, uint64_t amf_ue_ngap_id, - NGAP_Cause_PR group, long cause) -{ - NGAP_NGAP_PDU_t pdu; - NGAP_UnsuccessfulOutcome_t *unsuccessfulOutcome = NULL; - NGAP_PathSwitchRequestFailure_t *PathSwitchRequestFailure = NULL; - - NGAP_PathSwitchRequestFailureIEs_t *ie = NULL; - NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; - NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; - NGAP_Cause_t *Cause = NULL; - - ogs_debug("Path switch failure"); - - memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); - pdu.present = NGAP_NGAP_PDU_PR_unsuccessfulOutcome; - pdu.choice.unsuccessfulOutcome = - CALLOC(1, sizeof(NGAP_UnsuccessfulOutcome_t)); - - unsuccessfulOutcome = pdu.choice.unsuccessfulOutcome; - unsuccessfulOutcome->procedureCode = - NGAP_ProcedureCode_id_PathSwitchRequest; - unsuccessfulOutcome->criticality = NGAP_Criticality_reject; - unsuccessfulOutcome->value.present = - NGAP_UnsuccessfulOutcome__value_PR_PathSwitchRequestFailure; - - PathSwitchRequestFailure = - &unsuccessfulOutcome->value.choice.PathSwitchRequestFailure; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestFailureIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestFailure->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = - NGAP_PathSwitchRequestFailureIEs__value_PR_AMF_UE_NGAP_ID; - - AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestFailureIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestFailure->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = - NGAP_PathSwitchRequestFailureIEs__value_PR_RAN_UE_NGAP_ID; - - RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestFailureIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestFailure->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_Cause; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = NGAP_PathSwitchRequestFailureIEs__value_PR_Cause; - - Cause = &ie->value.choice.Cause; - - ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]", - ran_ue_ngap_id, (long long)amf_ue_ngap_id); - ogs_debug(" Group[%d] Cause[%d]", group, (int)cause); - - asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id); - *RAN_UE_NGAP_ID = ran_ue_ngap_id; - Cause->present = group; - Cause->choice.radioNetwork = cause; + SecurityContext->nextHopNH.size = OGS_SHA256_DIGEST_SIZE; + SecurityContext->nextHopNH.buf = + CALLOC(SecurityContext->nextHopNH.size, sizeof(uint8_t)); + SecurityContext->nextHopNH.bits_unused = 0; + memcpy(SecurityContext->nextHopNH.buf, + amf_ue->nh, SecurityContext->nextHopNH.size); + + PDUSessionResourceSwitchedList = + &ie->value.choice.PDUSessionResourceSwitchedList; + + ogs_list_for_each(&amf_ue->sess_list, sess) { + OCTET_STRING_t *transfer = NULL; + NGAP_PDUSessionResourceSwitchedItem_t *PDUSessionItem = NULL; + + if (!PDUSessionResourceSwitchedList) { + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSwitchedList; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_PDUSessionResourceSwitchedList; + + PDUSessionResourceSwitchedList = + &ie->value.choice.PDUSessionResourceSwitchedList; + } + + PDUSessionItem = + CALLOC(1, sizeof(NGAP_PDUSessionResourceSwitchedItem_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceSwitchedList->list, PDUSessionItem); + + PDUSessionItem->pDUSessionID = sess->psi; + + transfer = &PDUSessionItem->pathSwitchRequestAcknowledgeTransfer; + transfer->size = n2smbuf->len; + transfer->buf = CALLOC(transfer->size, sizeof(uint8_t)); + memcpy(transfer->buf, n2smbuf->data, transfer->size); + ogs_pkbuf_free(n2smbuf); + } + + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_AllowedNSSAI; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = + NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_AllowedNSSAI; + + AllowedNSSAI = &ie->value.choice.AllowedNSSAI; + + for (i = 0; i < amf_self()->num_of_plmn_support; i++) { + if (memcmp(&amf_ue->tai.plmn_id, + &amf_self()->plmn_support[i].plmn_id, OGS_PLMN_ID_LEN) != 0) + continue; + for (j = 0; j < amf_self()->plmn_support[i].num_of_s_nssai; j++) { + NGAP_AllowedNSSAI_Item_t *NGAP_AllowedNSSAI_Item = NULL; + NGAP_S_NSSAI_t *s_NSSAI = NULL; + NGAP_SST_t *sST = NULL; + + NGAP_AllowedNSSAI_Item = (NGAP_AllowedNSSAI_Item_t *) + CALLOC(1, sizeof(NGAP_AllowedNSSAI_Item_t)); + s_NSSAI = &NGAP_AllowedNSSAI_Item->s_NSSAI; + sST = &s_NSSAI->sST; + + ogs_asn_uint8_to_OCTET_STRING( + amf_self()->plmn_support[i].s_nssai[j].sst, sST); + if (amf_self()->plmn_support[i].s_nssai[j].sd.v != + OGS_S_NSSAI_NO_SD_VALUE) { + s_NSSAI->sD = CALLOC(1, sizeof(NGAP_SD_t)); + ogs_asn_uint24_to_OCTET_STRING( + amf_self()->plmn_support[i].s_nssai[j].sd, s_NSSAI->sD); + } + + ASN_SEQUENCE_ADD(&AllowedNSSAI->list, NGAP_AllowedNSSAI_Item); + } + } return ogs_ngap_encode(&pdu); } +#if 0 ogs_pkbuf_t *ngap_build_handover_command(ran_ue_t *source_ue) { int rv; @@ -2142,131 +2150,6 @@ ogs_pkbuf_t *ngap_build_error_indication( return ogs_ngap_encode(&pdu); } - - -ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue) -{ - ran_ue_t *ran_ue = NULL; - amf_sess_t *sess = NULL; - - NGAP_NGAP_PDU_t pdu; - NGAP_SuccessfulOutcome_t *successfulOutcome = NULL; - NGAP_PathSwitchRequestAcknowledge_t *PathSwitchRequestAcknowledge = NULL; - - NGAP_PathSwitchRequestAcknowledgeIEs_t *ie = NULL; - NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; - NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; - NGAP_SecurityContext_t *SecurityContext = NULL; - NGAP_PDUSessionResourceSwitchedList_t *PDUSessionResourceSwitchedList; - - ogs_assert(amf_ue); - ran_ue = ran_ue_cycle(amf_ue->ran_ue); - ogs_assert(ran_ue); - - memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); - pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome = - CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t)); - - successfulOutcome = pdu.choice.successfulOutcome; - successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PathSwitchRequest; - successfulOutcome->criticality = NGAP_Criticality_reject; - successfulOutcome->value.present = - NGAP_SuccessfulOutcome__value_PR_PathSwitchRequestAcknowledge; - - PathSwitchRequestAcknowledge = &successfulOutcome->value.choice.PathSwitchRequestAcknowledge; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = - NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_AMF_UE_NGAP_ID; - - AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = - NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_RAN_UE_NGAP_ID; - - RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_SecurityContext; - ie->criticality = NGAP_Criticality_reject; - ie->value.present = - NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_SecurityContext; - - SecurityContext = &ie->value.choice.SecurityContext; - - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSwitchedList; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = - NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_PDUSessionResourceSwitchedList; - - PDUSessionResourceSwitchedList = &ie->value.choice.PDUSessionResourceSwitchedList; - - ogs_list_for_each(&amf_ue->sess_list, sess) { - OCTET_STRING_t *transfer = NULL; - NGAP_PDUSessionResourceSwitchedItem_t *PDUSessionItem = NULL; - - if (!sess->pdu_session_resource_setup_request_transfer) continue; - - if (!PDUSessionResourceSwitchedList) { - ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestAcknowledgeIEs_t)); - ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie); - - ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSwitchedList; - ie->criticality = NGAP_Criticality_ignore; - ie->value.present = - NGAP_PathSwitchRequestAcknowledgeIEs__value_PR_PDUSessionResourceSwitchedList; - - PDUSessionResourceSwitchedList = &ie->value.choice.PDUSessionResourceSwitchedList; - } - - PDUSessionItem = CALLOC(1, - sizeof(NGAP_PDUSessionResourceSwitchedItem_t)); - ASN_SEQUENCE_ADD(&PDUSessionResourceSwitchedList->list, PDUSessionItem); - - PDUSessionItem->pDUSessionID = sess->psi; - - transfer = &PDUSessionItem->pathSwitchRequestAcknowledgeTransfer; - transfer->size = sess->pdu_session_resource_setup_request_transfer->len; - transfer->buf = CALLOC(transfer->size, sizeof(uint8_t)); - memcpy(transfer->buf, - sess->pdu_session_resource_setup_request_transfer->data, - transfer->size); - } - - ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]", - ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id); - - asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id); - *RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id; - - SecurityContext->nextHopChainingCount = amf_ue->nhcc; - SecurityContext->nextHopNH.size = OGS_SHA256_DIGEST_SIZE; - SecurityContext->nextHopNH.buf = - CALLOC(SecurityContext->nextHopNH.size, - sizeof(uint8_t)); - SecurityContext->nextHopNH.bits_unused = 0; - memcpy(SecurityContext->nextHopNH.buf, - amf_ue->nh, SecurityContext->nextHopNH.size); - - return ogs_ngap_encode(&pdu); -} - - #if 0 ogs_pkbuf_t *ngap_build_s1_reset( NGAP_Cause_PR group, long cause, diff --git a/src/amf/ngap-build.h b/src/amf/ngap-build.h index c5353f154..6a693dbc2 100644 --- a/src/amf/ngap-build.h +++ b/src/amf/ngap-build.h @@ -54,10 +54,7 @@ ogs_pkbuf_t *ngap_build_paging( ogs_pkbuf_t *ngap_build_amf_configuration_transfer( NGAP_SONConfigurationTransfer_t *son_configuration_transfer); -ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue); -ogs_pkbuf_t *ngap_build_path_switch_failure( - uint32_t ran_ue_ngap_id, uint64_t amf_ue_ngap_id, - NGAP_Cause_PR group, long cause); +ogs_pkbuf_t *ngap_build_path_switch_ack(amf_ue_t *amf_ue, ogs_pkbuf_t *n2smbuf); ogs_pkbuf_t *ngap_build_handover_command(ran_ue_t *source_ue); ogs_pkbuf_t *ngap_build_handover_preparation_failure( diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index 3151c47e9..3746ebf9e 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -465,9 +465,13 @@ void ngap_handle_initial_ue_message(amf_gnb_t *gnb, ogs_ngap_message_t *message) ogs_ngap_ASN_to_5gs_tai( &userLocationInformationNR->tAI, &ran_ue->saved.tai); - } else + } else { ogs_error("Not implemented UserLocationInformation[%d]", UserLocationInformation->present); + ngap_send_error_indication(gnb, &ran_ue->ran_ue_ngap_id, NULL, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_unspecified); + return; + } ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld] " "TAC[%d] CellID[0x%llx]", @@ -1736,6 +1740,8 @@ void ngap_handle_path_switch_request( NGAP_EUTRAencryptionAlgorithms_t *eUTRAencryptionAlgorithms = NULL; NGAP_EUTRAintegrityProtectionAlgorithms_t *eUTRAintegrityProtectionAlgorithms = NULL; + uint16_t nea = 0, nia = 0, eps_ea = 0, eps_ia = 0; + uint8_t nea0 = 0, nia0 = 0, eps_ea0 = 0, eps_ia0 = 0; NGAP_PDUSessionResourceToBeSwitchedDLItem_t *PDUSessionItem = NULL; OCTET_STRING_t *transfer = NULL; @@ -1827,6 +1833,20 @@ void ngap_handle_path_switch_request( return; } + if (!UESecurityCapabilities) { + ogs_error("No UESecurityCapabilities"); + ngap_send_error_indication(gnb, &ran_ue->ran_ue_ngap_id, NULL, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + if (!PDUSessionResourceToBeSwitchedDLList) { + ogs_error("No PDUSessionResourceToBeSwitchedDLList"); + ngap_send_error_indication(gnb, &ran_ue->ran_ue_ngap_id, NULL, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + if (UserLocationInformation->present == NGAP_UserLocationInformation_PR_userLocationInformationNR) { NGAP_UserLocationInformationNR_t *userLocationInformationNR = @@ -1837,19 +1857,38 @@ void ngap_handle_path_switch_request( ogs_ngap_ASN_to_5gs_tai( &userLocationInformationNR->tAI, &ran_ue->saved.tai); - } else + } else { ogs_error("Not implemented UserLocationInformation[%d]", UserLocationInformation->present); - - if (!UESecurityCapabilities) { - ogs_error("No UESecurityCapabilities"); ngap_send_error_indication(gnb, &ran_ue->ran_ue_ngap_id, NULL, - NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_unspecified); return; } - nRencryptionAlgorithms = - &UESecurityCapabilities->nRencryptionAlgorithms; + if (SECURITY_CONTEXT_IS_VALID(amf_ue)) { + amf_ue->nhcc++; + ogs_kdf_nh_gnb(amf_ue->kamf, amf_ue->nh, amf_ue->nh); + } else { + ogs_error("No Security Context"); + ngap_send_error_indication(gnb, &ran_ue->ran_ue_ngap_id, NULL, + NGAP_Cause_PR_nas, NGAP_CauseNas_authentication_failure); + return; + } + + ran_ue->ran_ue_ngap_id = *RAN_UE_NGAP_ID; + + ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld] ", + ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id); + ogs_debug(" [OLD] TAC[%d] CellID[0x%llx]", + amf_ue->tai.tac.v, (long long)amf_ue->nr_cgi.cell_id); + ogs_debug(" [NEW] TAC[%d] CellID[0x%llx]", + ran_ue->saved.tai.tac.v, (long long)ran_ue->saved.nr_cgi.cell_id); + + /* Copy TAI and ECGI from ran_ue */ + memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t)); + memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t)); + + nRencryptionAlgorithms = &UESecurityCapabilities->nRencryptionAlgorithms; nRintegrityProtectionAlgorithms = &UESecurityCapabilities->nRintegrityProtectionAlgorithms; eUTRAencryptionAlgorithms = @@ -1857,19 +1896,29 @@ void ngap_handle_path_switch_request( eUTRAintegrityProtectionAlgorithms = &UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms; - amf_ue->ue_security_capability.nea = nRencryptionAlgorithms->buf[0]; - amf_ue->ue_security_capability.nia = - nRintegrityProtectionAlgorithms->buf[0]; - amf_ue->ue_security_capability.eea = eUTRAencryptionAlgorithms->buf[0]; - amf_ue->ue_security_capability.eia = - eUTRAintegrityProtectionAlgorithms->buf[0]; - - if (!PDUSessionResourceToBeSwitchedDLList) { - ogs_error("No PDUSessionResourceToBeSwitchedDLList"); - ngap_send_error_indication(gnb, &ran_ue->ran_ue_ngap_id, NULL, - NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); - return; - } + memcpy(&nea, nRencryptionAlgorithms->buf, sizeof(nea)); + nea = be16toh(nea); + nea0 = amf_ue->ue_security_capability.nea0; + amf_ue->ue_security_capability.nea = nea >> 9; + amf_ue->ue_security_capability.nea0 = nea0; + + memcpy(&nia, nRintegrityProtectionAlgorithms->buf, sizeof(nia)); + nia = be16toh(nia); + nia0 = amf_ue->ue_security_capability.nia0; + amf_ue->ue_security_capability.nia = nia >> 9; + amf_ue->ue_security_capability.nia0 = nia0; + + memcpy(&eps_ea, eUTRAencryptionAlgorithms->buf, sizeof(eps_ea)); + eps_ea = be16toh(eps_ea); + eps_ea0 = amf_ue->ue_security_capability.eps_ea0; + amf_ue->ue_security_capability.eps_ea = eps_ea >> 9; + amf_ue->ue_security_capability.eps_ea0 = eps_ea0; + + memcpy(&eps_ia, eUTRAintegrityProtectionAlgorithms->buf, sizeof(eps_ia)); + eps_ia = be16toh(eps_ia); + eps_ia0 = amf_ue->ue_security_capability.eps_ia0; + amf_ue->ue_security_capability.eps_ia = eps_ia >> 9; + amf_ue->ue_security_capability.eps_ia0 = eps_ia0; for (i = 0; i < PDUSessionResourceToBeSwitchedDLList->list.count; i++) { amf_sess_t *sess = NULL; @@ -1930,4 +1979,6 @@ void ngap_handle_path_switch_request( ogs_pkbuf_free(param.n2smbuf); } + + ran_ue_switch_to_gnb(ran_ue, gnb); } diff --git a/src/amf/ngap-path.c b/src/amf/ngap-path.c index 6d91d0a4b..07e7517f6 100644 --- a/src/amf/ngap-path.c +++ b/src/amf/ngap-path.c @@ -387,20 +387,28 @@ void ngap_send_amf_configuration_transfer( ogs_expect(rv == OGS_OK); } -void ngap_send_path_switch_ack(amf_ue_t *amf_ue) +#endif + +void ngap_send_path_switch_ack(amf_sess_t *sess, ogs_pkbuf_t *n2smbuf) { int rv; + + amf_ue_t *amf_ue = NULL; ogs_pkbuf_t *ngapbuf = NULL; + ogs_assert(sess); + amf_ue = sess->amf_ue; ogs_assert(amf_ue); + ogs_assert(n2smbuf); - ngapbuf = ngap_build_path_switch_ack(amf_ue); + ngapbuf = ngap_build_path_switch_ack(amf_ue, n2smbuf); ogs_expect_or_return(ngapbuf); rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf); ogs_expect(rv == OGS_OK); } +#if 0 void ngap_send_handover_command(ran_ue_t *source_ue) { int rv; diff --git a/src/amf/ngap-path.h b/src/amf/ngap-path.h index ff3b534b3..8d0e5020d 100644 --- a/src/amf/ngap-path.h +++ b/src/amf/ngap-path.h @@ -69,7 +69,7 @@ void ngap_send_amf_configuration_transfer( amf_gnb_t *target_gnb, NGAP_SONConfigurationTransfer_t *SONConfigurationTransfer); -void ngap_send_path_switch_ack(amf_ue_t *amf_ue); +void ngap_send_path_switch_ack(amf_sess_t *sess, ogs_pkbuf_t *n2smbuf); void ngap_send_handover_command(ran_ue_t *source_ue); void ngap_send_handover_preparation_failure( diff --git a/src/amf/ngap-sm.c b/src/amf/ngap-sm.c index 7900dfa00..3c0a962da 100644 --- a/src/amf/ngap-sm.c +++ b/src/amf/ngap-sm.c @@ -94,10 +94,10 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e) case NGAP_ProcedureCode_id_UEContextReleaseRequest: ngap_handle_ue_context_release_request( gnb, pdu); break; -#if 0 case NGAP_ProcedureCode_id_PathSwitchRequest: ngap_handle_path_switch_request(gnb, pdu); break; +#if 0 case NGAP_ProcedureCode_id_eNBConfigurationTransfer: pkbuf = e->pkbuf; ogs_assert(pkbuf); diff --git a/src/amf/nsmf-handler.c b/src/amf/nsmf-handler.c index 8e9e8f643..bf6e15039 100644 --- a/src/amf/nsmf-handler.c +++ b/src/amf/nsmf-handler.c @@ -252,6 +252,12 @@ int amf_nsmf_pdu_session_handle_update_sm_context( nas_send_pdu_session_release_command(sess, n1smbuf, n2smbuf); break; + case OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK: + n2smbuf = ogs_pkbuf_copy(n2smbuf); + ogs_assert(n2smbuf); + + ngap_send_path_switch_ack(sess, n2smbuf); + break; default: ogs_error("Not implemented [%d]", SmContextUpdatedData->n2_sm_info_type); diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c index 9f748704d..e62b40d3c 100644 --- a/src/mme/s1ap-handler.c +++ b/src/mme/s1ap-handler.c @@ -1208,6 +1208,7 @@ void s1ap_handle_path_switch_request( S1AP_EncryptionAlgorithms_t *encryptionAlgorithms = NULL; S1AP_IntegrityProtectionAlgorithms_t *integrityProtectionAlgorithms = NULL; uint16_t eea = 0, eia = 0; + uint8_t eea0 = 0, eia0 = 0; enb_ue_t *enb_ue = NULL; mme_ue_t *mme_ue = NULL; @@ -1342,13 +1343,15 @@ void s1ap_handle_path_switch_request( memcpy(&eea, encryptionAlgorithms->buf, sizeof(eea)); eea = be16toh(eea); + eea0 = mme_ue->ue_network_capability.eea0; mme_ue->ue_network_capability.eea = eea >> 9; - mme_ue->ue_network_capability.eea0 = 1; + mme_ue->ue_network_capability.eea0 = eea0; memcpy(&eia, integrityProtectionAlgorithms->buf, sizeof(eia)); eia = be16toh(eia); + eia0 = mme_ue->ue_network_capability.eia0; mme_ue->ue_network_capability.eia = eia >> 9; - mme_ue->ue_network_capability.eia0 = 0; + mme_ue->ue_network_capability.eia0 = eia0; ogs_assert(E_RABToBeSwitchedDLList); for (i = 0; i < E_RABToBeSwitchedDLList->list.count; i++) { diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index f3d1d80d7..a10795e2f 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -310,6 +310,16 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) smf_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT); break; + case OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ: + rv = ngap_handle_pdu_session_resource_to_be_switched_dl_transfer( + sess, stream, pkbuf); + if (rv != OGS_OK) { + ogs_error("[%s:%d] Cannot handle NGAP message", + smf_ue->supi, sess->psi); + OGS_FSM_TRAN(s, smf_gsm_state_exception); + } + break; + default: ogs_error("Unknown message[%d]", e->ngap.type); } diff --git a/src/smf/n4-build.c b/src/smf/n4-build.c index 47ab61ffa..9ad2a68ff 100644 --- a/src/smf/n4-build.c +++ b/src/smf/n4-build.c @@ -283,7 +283,8 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( i++; } } - if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE) { + if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE + || modify_flags & OGS_PFCP_MODIFY_UL_ONLY) { /* Update FAR - Only DL */ i = 0; if (qos_flow->dl_far) { diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 1f86ce22d..a5af334fe 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -298,8 +298,17 @@ void smf_5gc_n4_handle_session_modification_response( } if (flags & OGS_PFCP_MODIFY_ACTIVATE) { - /* ACTIVATED Is NOT Inlcuded in RESPONSE */ - smf_sbi_send_sm_context_updated_data(sess, stream, 0); + if (flags & OGS_PFCP_MODIFY_PATH_SWITCH) { + ogs_pkbuf_t *n2smbuf = + ngap_build_path_switch_request_ack_transfer(sess); + ogs_assert(n2smbuf); + + smf_sbi_send_sm_context_updated_data_with_n2buf(sess, stream, + OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK, n2smbuf); + } else { + /* ACTIVATED Is NOT Included in RESPONSE */ + smf_sbi_send_sm_context_updated_data(sess, stream, 0); + } } else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) { /* Only ACTIVING & DEACTIVATED is Included */ diff --git a/src/smf/ngap-build.c b/src/smf/ngap-build.c index f5a85d95d..ab7f331fb 100644 --- a/src/smf/ngap-build.c +++ b/src/smf/ngap-build.c @@ -294,3 +294,39 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer( return ogs_asn_encode( &asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, &message); } + +ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess) +{ + NGAP_PathSwitchRequestAcknowledgeTransfer_t message; + +#if 0 + ogs_ip_t upf_n3_ip; + + NGAP_UPTransportLayerInformation_t *UPTransportLayerInformation = NULL; + NGAP_GTPTunnel_t *gTPTunnel = NULL; + + ogs_assert(sess); +#endif + + ogs_debug("PathSwitchRequestAcknowledgeTransfer"); + memset(&message, 0, sizeof(NGAP_PathSwitchRequestAcknowledgeTransfer_t)); + +#if 0 /* The following is optional. So I've removed */ + + message.uL_NGU_UP_TNLInformation = CALLOC(1, sizeof(NGAP_UPTransportLayerInformation_t)); + UPTransportLayerInformation = message.uL_NGU_UP_TNLInformation; + + gTPTunnel = CALLOC(1, sizeof(struct NGAP_GTPTunnel)); + UPTransportLayerInformation->present = + NGAP_UPTransportLayerInformation_PR_gTPTunnel; + UPTransportLayerInformation->choice.gTPTunnel = gTPTunnel; + + ogs_sockaddr_to_ip(sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip); + ogs_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress); + ogs_asn_uint32_to_OCTET_STRING(sess->upf_n3_teid, &gTPTunnel->gTP_TEID); + +#endif + + return ogs_asn_encode( + &asn_DEF_NGAP_PathSwitchRequestAcknowledgeTransfer, &message); +} diff --git a/src/smf/ngap-build.h b/src/smf/ngap-build.h index 0f3d1bd5b..a56869691 100644 --- a/src/smf/ngap-build.h +++ b/src/smf/ngap-build.h @@ -34,7 +34,7 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer( NGAP_Cause_PR group, long cause); - +ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess); #ifdef __cplusplus } #endif diff --git a/src/smf/ngap-handler.c b/src/smf/ngap-handler.c index 8532e69ae..e9aa5afc4 100644 --- a/src/smf/ngap-handler.c +++ b/src/smf/ngap-handler.c @@ -28,8 +28,8 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( smf_bearer_t *qos_flow = NULL; int rv, i; - uint32_t upf_n3_teid; - ogs_ip_t upf_n3_ip; + uint32_t gnb_n3_teid; + ogs_ip_t gnb_n3_ip; ogs_pfcp_far_t *dl_far = NULL; bool far_update = false; @@ -91,17 +91,17 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( } ogs_asn_BIT_STRING_to_ip( - &gTPTunnel->transportLayerAddress, &upf_n3_ip); - ogs_asn_OCTET_STRING_to_uint32(&gTPTunnel->gTP_TEID, &upf_n3_teid); + &gTPTunnel->transportLayerAddress, &gnb_n3_ip); + ogs_asn_OCTET_STRING_to_uint32(&gTPTunnel->gTP_TEID, &gnb_n3_teid); /* Need to Update? */ - if (memcmp(&sess->gnb_n3_ip, &upf_n3_ip, sizeof(sess->gnb_n3_ip)) != 0 || - sess->gnb_n3_teid != upf_n3_teid) + if (memcmp(&sess->gnb_n3_ip, &gnb_n3_ip, sizeof(sess->gnb_n3_ip)) != 0 || + sess->gnb_n3_teid != gnb_n3_teid) far_update = true; /* Setup FAR */ - memcpy(&sess->gnb_n3_ip, &upf_n3_ip, sizeof(sess->gnb_n3_ip)); - sess->gnb_n3_teid = upf_n3_teid; + memcpy(&sess->gnb_n3_ip, &gnb_n3_ip, sizeof(sess->gnb_n3_ip)); + sess->gnb_n3_teid = gnb_n3_teid; associatedQosFlowList = &dLQosFlowPerTNLInformation->associatedQosFlowList; for (i = 0; i < associatedQosFlowList->list.count; i++) { @@ -140,7 +140,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( smf_5gc_pfcp_send_session_modification_request( sess, stream, OGS_PFCP_MODIFY_ACTIVATE); } else { - /* ACTIVATED Is NOT Inlcuded in RESPONSE */ + /* ACTIVATED Is NOT Included in RESPONSE */ smf_sbi_send_sm_context_updated_data(sess, stream, 0); } @@ -229,3 +229,126 @@ cleanup: &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, &message); return rv; } + +int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer( + smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf) +{ + smf_ue_t *smf_ue = NULL; + smf_bearer_t *qos_flow = NULL; + int rv, i; + + uint32_t gnb_n3_teid; + ogs_ip_t gnb_n3_ip; + + ogs_pfcp_far_t *dl_far = NULL; + bool far_update = false; + + NGAP_PathSwitchRequestTransfer_t message; + + NGAP_UPTransportLayerInformation_t *dL_NGU_UP_TNLInformation = NULL; + NGAP_GTPTunnel_t *gTPTunnel = NULL; + + NGAP_QosFlowAcceptedList_t *qosFlowAcceptedList = NULL; + + ogs_assert(pkbuf); + ogs_assert(stream); + + ogs_assert(sess); + smf_ue = sess->smf_ue; + ogs_assert(smf_ue); + + rv = ogs_asn_decode(&asn_DEF_NGAP_PathSwitchRequestTransfer, + &message, sizeof(message), pkbuf); + if (rv != OGS_OK) { + ogs_error("[%s:%d] Cannot decode NGAP message", + smf_ue->supi, sess->psi); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No N2 SM Info Type", smf_ue->supi, NULL, NULL); + goto cleanup; + } + + rv = OGS_ERROR; + + dL_NGU_UP_TNLInformation = &message.dL_NGU_UP_TNLInformation; + if (dL_NGU_UP_TNLInformation->present != + NGAP_UPTransportLayerInformation_PR_gTPTunnel) { + ogs_error( + "[%s:%d] Unknown NGAP_UPTransportLayerInformation.present [%d]", + smf_ue->supi, sess->psi, dL_NGU_UP_TNLInformation->present); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "Unknown NGAP_UPTransportLayerInformation.present", + smf_ue->supi, NULL, NULL); + goto cleanup; + } + + gTPTunnel = dL_NGU_UP_TNLInformation->choice.gTPTunnel; + if (!gTPTunnel) { + ogs_error("[%s:%d] No GTPTunnel", smf_ue->supi, sess->psi); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No GTPTunnel", smf_ue->supi, NULL, NULL); + goto cleanup; + } + + ogs_asn_BIT_STRING_to_ip(&gTPTunnel->transportLayerAddress, &gnb_n3_ip); + ogs_asn_OCTET_STRING_to_uint32(&gTPTunnel->gTP_TEID, &gnb_n3_teid); + + /* Need to Update? */ + if (memcmp(&sess->gnb_n3_ip, &gnb_n3_ip, sizeof(sess->gnb_n3_ip)) != 0 || + sess->gnb_n3_teid != gnb_n3_teid) + far_update = true; + + /* Setup FAR */ + memcpy(&sess->gnb_n3_ip, &gnb_n3_ip, sizeof(sess->gnb_n3_ip)); + sess->gnb_n3_teid = gnb_n3_teid; + + qosFlowAcceptedList = &message.qosFlowAcceptedList; + for (i = 0; i < qosFlowAcceptedList->list.count; i++) { + NGAP_QosFlowAcceptedItem_t *acceptedQosFlowItem = NULL; + acceptedQosFlowItem = (NGAP_QosFlowAcceptedItem_t *) + qosFlowAcceptedList->list.array[i]; + if (acceptedQosFlowItem) { + qos_flow = smf_qos_flow_find_by_qfi(sess, + acceptedQosFlowItem->qosFlowIdentifier); + + if (qos_flow) { + dl_far = qos_flow->dl_far; + ogs_assert(dl_far); + if (dl_far->apply_action != OGS_PFCP_APPLY_ACTION_FORW) { + far_update = true; + } + + dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; + ogs_pfcp_ip_to_outer_header_creation( + &sess->gnb_n3_ip, + &dl_far->outer_header_creation, + &dl_far->outer_header_creation_len); + dl_far->outer_header_creation.teid = sess->gnb_n3_teid; + } else { + ogs_error("[%s:%d] No QoS flow", smf_ue->supi, sess->psi); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No QoS flow", smf_ue->supi, NULL, NULL); + goto cleanup; + } + } + } + + if (far_update) { + smf_5gc_pfcp_send_session_modification_request( + sess, stream, + OGS_PFCP_MODIFY_ACTIVATE | OGS_PFCP_MODIFY_PATH_SWITCH | + OGS_PFCP_MODIFY_END_MARKER); + } else { + /* ACTIVATED Is NOT Included in RESPONSE */ + smf_sbi_send_sm_context_updated_data(sess, stream, 0); + } + + rv = OGS_OK; + +cleanup: + ogs_asn_free(&asn_DEF_NGAP_PathSwitchRequestTransfer, &message); + return rv; +} diff --git a/src/smf/ngap-handler.h b/src/smf/ngap-handler.h index 26581382e..8f56ff331 100644 --- a/src/smf/ngap-handler.h +++ b/src/smf/ngap-handler.h @@ -30,6 +30,8 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf); int ngap_handle_pdu_session_resource_modify_response_transfer( smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf); +int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer( + smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf); #ifdef __cplusplus } diff --git a/src/smf/sbi-path.c b/src/smf/sbi-path.c index 59b0c2a16..598a26f2b 100644 --- a/src/smf/sbi-path.c +++ b/src/smf/sbi-path.c @@ -432,3 +432,45 @@ void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess) ogs_assert(request); ogs_sbi_client_send_request(client, client_notify_cb, request, NULL); } + +void smf_sbi_send_sm_context_updated_data_with_n2buf( + smf_sess_t *sess, ogs_sbi_stream_t *stream, + OpenAPI_n2_sm_info_type_e n2_sm_info_type, ogs_pkbuf_t *n2smbuf) +{ + ogs_sbi_message_t sendmsg; + ogs_sbi_response_t *response = NULL; + + OpenAPI_sm_context_updated_data_t SmContextUpdatedData; + OpenAPI_ref_to_binary_data_t n2SmInfo; + + ogs_assert(sess); + ogs_assert(stream); + + memset(&sendmsg, 0, sizeof(sendmsg)); + + memset(&SmContextUpdatedData, 0, sizeof(SmContextUpdatedData)); + + sendmsg.num_of_part = 0; + + sendmsg.SmContextUpdatedData = &SmContextUpdatedData; + + if (n2smbuf) { + SmContextUpdatedData.n2_sm_info_type = n2_sm_info_type; + SmContextUpdatedData.n2_sm_info = &n2SmInfo; + n2SmInfo.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID; + sendmsg.part[sendmsg.num_of_part].content_id = + (char *)OGS_SBI_CONTENT_NGAP_SM_ID; + sendmsg.part[sendmsg.num_of_part].content_type = + (char *)OGS_SBI_CONTENT_NGAP_TYPE; + sendmsg.part[sendmsg.num_of_part].pkbuf = n2smbuf; + sendmsg.num_of_part++; + } + + response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK); + ogs_assert(response); + + ogs_sbi_server_send_response(stream, response); + + if (n2smbuf) + ogs_pkbuf_free(n2smbuf); +} \ No newline at end of file diff --git a/src/smf/sbi-path.h b/src/smf/sbi-path.h index 4955269ab..3f24e6538 100644 --- a/src/smf/sbi-path.h +++ b/src/smf/sbi-path.h @@ -57,6 +57,9 @@ void smf_sbi_send_sm_context_update_error( ogs_sbi_stream_t *stream, int status, const char *title, const char *detail, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf); +void smf_sbi_send_sm_context_updated_data_with_n2buf( + smf_sess_t *sess, ogs_sbi_stream_t *stream, + OpenAPI_n2_sm_info_type_e n2_sm_info_type, ogs_pkbuf_t *n2smbuf); void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess); diff --git a/src/udm/nudr-handler.c b/src/udm/nudr-handler.c index c2df36a0f..ee26d56c4 100644 --- a/src/udm/nudr-handler.c +++ b/src/udm/nudr-handler.c @@ -29,15 +29,22 @@ bool udm_nudr_dr_handle_subscription_authentication( ogs_sbi_header_t header; ogs_sbi_response_t *response = NULL; +#if 1 #if 0 - const char *tmp[1] = "de8ca9df474091fe4e9263c5daa907e9"; - const char *tmp[1] = "cc3766b98a8031a7286a68c7f577ed2e"; /* For test */ + const char *tmp[1] = { "de8ca9df474091fe4e9263c5daa907e9" }; + /* PFCP test */ + const char *tmp[1] = { "cc3766b98a8031a7286a68c7f577ed2e" }; +#endif + /* Xn-Handover */ + const char *tmp[1] = { "5ca0df8c9bb8dbcf3c2a7dd448da1369" }; +#if 0 /* ISSUE-482 */ const char *tmp[2] = { "3a1fa0f51fe50f324f8522b220fc62a2", "cc5539bf72824c879e47e73efc885021" }; +#endif static int step = 0; #endif @@ -183,10 +190,12 @@ bool udm_nudr_dr_handle_subscription_authentication( AuthenticationInfoResult.auth_type = udm_ue->auth_type; ogs_random(udm_ue->rand, OGS_RAND_LEN); -#if 0 +#if 1 OGS_HEX(tmp[step], strlen(tmp[step]), udm_ue->rand); +#if 0 if (step == 0) step = 1; /* For supporting authentication failure */ else step = 0; +#endif #endif milenage_generate(udm_ue->opc, udm_ue->amf, udm_ue->k, udm_ue->sqn, diff --git a/tests/app/app-init.c b/tests/app/app-init.c index cda194518..2172af1fb 100644 --- a/tests/app/app-init.c +++ b/tests/app/app-init.c @@ -119,7 +119,7 @@ void test_app_init(void) { ogs_log_install_domain(&__ogs_sctp_domain, "sctp", OGS_LOG_ERROR); ogs_log_install_domain(&__ogs_s1ap_domain, "s1ap", OGS_LOG_ERROR); - ogs_log_install_domain(&__ogs_s1ap_domain, "ngap", OGS_LOG_ERROR); + ogs_log_install_domain(&__ogs_ngap_domain, "ngap", OGS_LOG_ERROR); ogs_log_install_domain(&__ogs_diam_domain, "diam", OGS_LOG_ERROR); ogs_log_install_domain(&__ogs_dbi_domain, "dbi", OGS_LOG_ERROR); ogs_log_install_domain(&__ogs_nas_domain, "nas", OGS_LOG_ERROR); diff --git a/tests/common/context.c b/tests/common/context.c index 044c1e3d9..815e4b322 100644 --- a/tests/common/context.c +++ b/tests/common/context.c @@ -874,6 +874,15 @@ test_ue_t *test_ue_add_by_suci( test_ue->nas.access_type = OGS_ACCESS_TYPE_3GPP; test_ue->abba_len = 2; + test_ue->ue_security_capability.nea = 0xf0; + test_ue->ue_security_capability.nia = 0xf0; +#if 0 + test_ue->ue_security_capability.eps_ea = 0xf0; + test_ue->ue_security_capability.eps_ia = 0xf0; +#endif + test_ue->ue_network_capability.eea = 0xf0; + test_ue->ue_network_capability.eia = 0xf0; + memcpy(&test_ue->e_tai, &test_self()->e_tai, sizeof(ogs_eps_tai_t)); memcpy(&test_ue->e_cgi.plmn_id, &test_ue->e_tai.plmn_id, OGS_PLMN_ID_LEN); diff --git a/tests/common/context.h b/tests/common/context.h index ab5620b79..bc1713023 100644 --- a/tests/common/context.h +++ b/tests/common/context.h @@ -363,6 +363,9 @@ typedef struct test_ue_s { int security_context_available; int mac_failed; + ogs_nas_ue_security_capability_t ue_security_capability; + ogs_nas_ue_network_capability_t ue_network_capability; + test_initial_ue_param_t initial_ue_param; test_registration_request_param_t registration_request_param; diff --git a/tests/common/gmm-build.c b/tests/common/gmm-build.c index 3de26ac17..5ba156c05 100644 --- a/tests/common/gmm-build.c +++ b/tests/common/gmm-build.c @@ -133,14 +133,20 @@ ogs_pkbuf_t *testgmm_build_registration_request( registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT; ue_security_capability->length = 2; - ue_security_capability->nea = 0xf0; - ue_security_capability->nia = 0xf0; + ue_security_capability->nea = test_ue->ue_security_capability.nea; + ue_security_capability->nia = test_ue->ue_security_capability.nia; + if (test_ue->ue_security_capability.eps_ea || + test_ue->ue_security_capability.eps_ia) { + ue_security_capability->length = 4; + ue_security_capability->eps_ea = test_ue->ue_security_capability.eps_ea; + ue_security_capability->eps_ia = test_ue->ue_security_capability.eps_ia; + } registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_PRESENT; s1_ue_network_capability->length = 7; - s1_ue_network_capability->eea = 0xf0; - s1_ue_network_capability->eia = 0xf0; + s1_ue_network_capability->eea = test_ue->ue_network_capability.eea; + s1_ue_network_capability->eia = test_ue->ue_network_capability.eia; s1_ue_network_capability->uea = 0xc0; s1_ue_network_capability->uia = 0xc0; s1_ue_network_capability->notification_procedure = 1; diff --git a/tests/common/ngap-build.c b/tests/common/ngap-build.c index 4fd1513b9..71da038c0 100644 --- a/tests/common/ngap-build.c +++ b/tests/common/ngap-build.c @@ -23,6 +23,8 @@ static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer( test_sess_t *sess); static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer( test_bearer_t *qos_flow); +static ogs_pkbuf_t *testngap_build_path_switch_request_trasfer( + test_sess_t *sess); ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize) { @@ -244,10 +246,10 @@ ogs_pkbuf_t *testngap_build_initial_ue_message( CALLOC(1, sizeof(NGAP_UserLocationInformationNR_t)); nR_CGI = &userLocationInformationNR->nR_CGI; - ogs_ngap_nr_cgi_to_ASN(&test_self()->nr_cgi, nR_CGI); + ogs_ngap_nr_cgi_to_ASN(&test_ue->nr_cgi, nR_CGI); tAI = &userLocationInformationNR->tAI; - ogs_ngap_5gs_tai_to_ASN(&test_self()->nr_tai, tAI); + ogs_ngap_5gs_tai_to_ASN(&test_ue->nr_tai, tAI); UserLocationInformation->present = NGAP_UserLocationInformation_PR_userLocationInformationNR; @@ -381,10 +383,10 @@ ogs_pkbuf_t *testngap_build_uplink_nas_transport( CALLOC(1, sizeof(NGAP_UserLocationInformationNR_t)); nR_CGI = &userLocationInformationNR->nR_CGI; - ogs_ngap_nr_cgi_to_ASN(&test_self()->nr_cgi, nR_CGI); + ogs_ngap_nr_cgi_to_ASN(&test_ue->nr_cgi, nR_CGI); tAI = &userLocationInformationNR->tAI; - ogs_ngap_5gs_tai_to_ASN(&test_self()->nr_tai, tAI); + ogs_ngap_5gs_tai_to_ASN(&test_ue->nr_tai, tAI); UserLocationInformation->present = NGAP_UserLocationInformation_PR_userLocationInformationNR; @@ -1040,6 +1042,171 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response( return ogs_ngap_encode(&pdu); } +ogs_pkbuf_t *testngap_build_path_switch_request(test_sess_t *sess) +{ + int rv; + + test_ue_t *test_ue = NULL; + + ogs_pkbuf_t *n2smbuf = NULL; + ogs_pkbuf_t *ngapbuf = NULL; + + NGAP_NGAP_PDU_t pdu; + NGAP_InitiatingMessage_t *initiatingMessage = NULL; + NGAP_PathSwitchRequest_t *PathSwitchRequest = NULL; + + NGAP_PathSwitchRequestIEs_t *ie = NULL; + + NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; + NGAP_UserLocationInformation_t *UserLocationInformation = NULL; + NGAP_UESecurityCapabilities_t *UESecurityCapabilities = NULL; + NGAP_PDUSessionResourceToBeSwitchedDLList_t + *PDUSessionResourceToBeSwitchedDLList = NULL; + + NGAP_PDUSessionResourceToBeSwitchedDLItem_t *PDUSessionItem = NULL; + + NGAP_UserLocationInformationNR_t *userLocationInformationNR = NULL; + NGAP_NR_CGI_t *nR_CGI = NULL; + NGAP_TAI_t *tAI = NULL; + + OCTET_STRING_t *transfer = NULL; + ogs_assert(sess); + test_ue = sess->test_ue; + ogs_assert(test_ue); + + memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t)); + + initiatingMessage = pdu.choice.initiatingMessage; + initiatingMessage->procedureCode = + NGAP_ProcedureCode_id_PathSwitchRequest; + initiatingMessage->criticality = NGAP_Criticality_reject; + initiatingMessage->value.present = + NGAP_InitiatingMessage__value_PR_PathSwitchRequest; + + PathSwitchRequest = + &initiatingMessage->value.choice.PathSwitchRequest; + + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = + NGAP_PathSwitchRequestIEs__value_PR_RAN_UE_NGAP_ID; + + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_SourceAMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = + NGAP_PathSwitchRequestIEs__value_PR_AMF_UE_NGAP_ID; + + AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; + + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = + NGAP_PathSwitchRequestIEs__value_PR_UserLocationInformation; + + UserLocationInformation = &ie->value.choice.UserLocationInformation; + + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_UESecurityCapabilities; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = + NGAP_PathSwitchRequestIEs__value_PR_UESecurityCapabilities; + + UESecurityCapabilities = &ie->value.choice.UESecurityCapabilities; + + ie = CALLOC(1, sizeof(NGAP_PathSwitchRequestIEs_t)); + ASN_SEQUENCE_ADD(&PathSwitchRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceToBeSwitchedDLList; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PathSwitchRequestIEs__value_PR_PDUSessionResourceToBeSwitchedDLList; + + PDUSessionResourceToBeSwitchedDLList = + &ie->value.choice.PDUSessionResourceToBeSwitchedDLList; + + asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id); + *RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id; + + userLocationInformationNR = + CALLOC(1, sizeof(NGAP_UserLocationInformationNR_t)); + + nR_CGI = &userLocationInformationNR->nR_CGI; + ogs_ngap_nr_cgi_to_ASN(&test_ue->nr_cgi, nR_CGI); + + tAI = &userLocationInformationNR->tAI; + ogs_ngap_5gs_tai_to_ASN(&test_ue->nr_tai, tAI); + + UserLocationInformation->present = + NGAP_UserLocationInformation_PR_userLocationInformationNR; + UserLocationInformation->choice.userLocationInformationNR = + userLocationInformationNR; + + UESecurityCapabilities->nRencryptionAlgorithms.size = 2; + UESecurityCapabilities->nRencryptionAlgorithms.buf = + CALLOC(UESecurityCapabilities-> + nRencryptionAlgorithms.size, sizeof(uint8_t)); + UESecurityCapabilities->nRencryptionAlgorithms.bits_unused = 0; + UESecurityCapabilities->nRencryptionAlgorithms.buf[0] = + (test_ue->ue_security_capability.nea << 1); + + UESecurityCapabilities->nRintegrityProtectionAlgorithms.size = 2; + UESecurityCapabilities->nRintegrityProtectionAlgorithms.buf = + CALLOC(UESecurityCapabilities-> + nRintegrityProtectionAlgorithms.size, sizeof(uint8_t)); + UESecurityCapabilities->nRintegrityProtectionAlgorithms.bits_unused = 0; + UESecurityCapabilities->nRintegrityProtectionAlgorithms.buf[0] = + (test_ue->ue_security_capability.nia << 1); + + UESecurityCapabilities->eUTRAencryptionAlgorithms.size = 2; + UESecurityCapabilities->eUTRAencryptionAlgorithms.buf = + CALLOC(UESecurityCapabilities-> + eUTRAencryptionAlgorithms.size, sizeof(uint8_t)); + UESecurityCapabilities->eUTRAencryptionAlgorithms.bits_unused = 0; + UESecurityCapabilities->eUTRAencryptionAlgorithms.buf[0] = + (test_ue->ue_security_capability.eps_ea << 1); + + UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms.size = 2; + UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms.buf = + CALLOC(UESecurityCapabilities-> + eUTRAintegrityProtectionAlgorithms.size, sizeof(uint8_t)); + UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms.bits_unused = 0; + UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms.buf[0] = + (test_ue->ue_security_capability.eps_ia << 1); + + PDUSessionItem = + CALLOC(1, sizeof(NGAP_PDUSessionResourceToBeSwitchedDLItem_t)); + ASN_SEQUENCE_ADD( + &PDUSessionResourceToBeSwitchedDLList->list, PDUSessionItem); + + PDUSessionItem->pDUSessionID = sess->psi; + + n2smbuf = testngap_build_path_switch_request_trasfer(sess); + ogs_assert(n2smbuf); + transfer = &PDUSessionItem->pathSwitchRequestTransfer; + + transfer->size = n2smbuf->len; + transfer->buf = CALLOC(transfer->size, sizeof(uint8_t)); + memcpy(transfer->buf, n2smbuf->data, transfer->size); + ogs_pkbuf_free(n2smbuf); + + return ogs_ngap_encode(&pdu); +} + static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer( test_sess_t *sess) { @@ -1123,3 +1290,58 @@ static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer( return ogs_asn_encode( &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, &message); } + +static ogs_pkbuf_t *testngap_build_path_switch_request_trasfer( + test_sess_t *sess) +{ + int rv; + + test_bearer_t *qos_flow = NULL; + + ogs_gtp_f_teid_t f_teid; + ogs_ip_t ip; + int len; + + ogs_assert(sess); + + NGAP_PathSwitchRequestTransfer_t message; + + NGAP_UPTransportLayerInformation_t *dL_NGU_UP_TNLInformation = NULL; + NGAP_GTPTunnel_t *gTPTunnel = NULL; + + NGAP_QosFlowAcceptedList_t *qosFlowAcceptedList = NULL; + NGAP_QosFlowAcceptedItem_t *qosFlowAcceptedItem = NULL; + + memset(&message, 0, sizeof(message)); + + dL_NGU_UP_TNLInformation = &message.dL_NGU_UP_TNLInformation; + + gTPTunnel = CALLOC(1, sizeof(struct NGAP_GTPTunnel)); + dL_NGU_UP_TNLInformation->present = + NGAP_UPTransportLayerInformation_PR_gTPTunnel; + dL_NGU_UP_TNLInformation->choice.gTPTunnel = gTPTunnel; + + ogs_assert(sess->gnb_n3_addr || sess->gnb_n3_addr6); + rv = ogs_gtp_sockaddr_to_f_teid( + sess->gnb_n3_addr, sess->gnb_n3_addr6, &f_teid, &len); + ogs_assert(rv == OGS_OK); + + rv = ogs_gtp_f_teid_to_ip(&f_teid, &ip); + ogs_assert(rv == OGS_OK); + + ogs_asn_ip_to_BIT_STRING(&ip, &gTPTunnel->transportLayerAddress); + ogs_asn_uint32_to_OCTET_STRING(sess->gnb_n3_teid, &gTPTunnel->gTP_TEID); + + qosFlowAcceptedList = &message.qosFlowAcceptedList; + + ogs_list_for_each(&sess->bearer_list, qos_flow) { + qosFlowAcceptedItem = + CALLOC(1, sizeof(NGAP_QosFlowAcceptedItem_t)); + ASN_SEQUENCE_ADD(&qosFlowAcceptedList->list, qosFlowAcceptedItem); + + qosFlowAcceptedItem->qosFlowIdentifier = qos_flow->qfi; + } + + return ogs_asn_encode( + &asn_DEF_NGAP_PathSwitchRequestTransfer, &message); +} diff --git a/tests/common/ngap-build.h b/tests/common/ngap-build.h index 536bd02fa..c14ddb02c 100644 --- a/tests/common/ngap-build.h +++ b/tests/common/ngap-build.h @@ -49,6 +49,8 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response( ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response( test_sess_t *sess); +ogs_pkbuf_t *testngap_build_path_switch_request(test_sess_t *sess); + #ifdef __cplusplus } #endif diff --git a/tests/common/ngap-path.c b/tests/common/ngap-path.c index f2b3e397a..0d7e88a7a 100644 --- a/tests/common/ngap-path.c +++ b/tests/common/ngap-path.c @@ -79,6 +79,8 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf) case NGAP_ProcedureCode_id_NGSetup: testngap_handle_ng_setup_response(test_ue, pdu); break; + case NGAP_ProcedureCode_id_PathSwitchRequest: + break; default: ogs_error("Not implemented(choice:%d, proc:%d)", pdu->present, (int)successfulOutcome->procedureCode); diff --git a/tests/handover/5gc-xn-test.c b/tests/handover/5gc-xn-test.c new file mode 100644 index 000000000..b12dc8405 --- /dev/null +++ b/tests/handover/5gc-xn-test.c @@ -0,0 +1,541 @@ +/* + * Copyright (C) 2019,2020 by Lester Lee + * + * This file is part of Open5GS. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "test-common.h" + +static void test1_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *ngap1, *ngap2; + ogs_socknode_t *gtpu1, *gtpu2; + ogs_pkbuf_t *gmmbuf; + ogs_pkbuf_t *gsmbuf; + ogs_pkbuf_t *nasbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_ngap_message_t message; + int i; + + uint8_t tmp[OGS_MAX_SDU_LEN]; + char *_gtp_payload = "34ff0024" + "0000000100000085 010002004500001c 0c0b000040015a7a 0a2d00010a2d0002" + "00000964cd7c291f"; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *qos_flow = NULL; + + const char *_k_string = "70d49a71dd1a2b806a25abe0ef749f1e"; + uint8_t k[OGS_KEY_LEN]; + const char *_opc_string = "6f1bf53d624b3a43af6592854e2444c7"; + uint8_t opc[OGS_KEY_LEN]; + + mongoc_collection_t *collection = NULL; + bson_t *doc = NULL; + int64_t count = 0; + bson_error_t error; + const char *json = + "{" + "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, " + "\"imsi\" : \"901700000021309\"," + "\"ambr\" : { " + "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1024000\" } " + "}," + "\"pdn\" : [" + "{" + "\"apn\" : \"internet\", " + "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c7\" }, " + "\"ambr\" : {" + "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1024000\" } " + "}," + "\"qos\" : { " + "\"qci\" : 9, " + "\"arp\" : { " + "\"priority_level\" : 8," + "\"pre_emption_vulnerability\" : 1, " + "\"pre_emption_capability\" : 1" + "} " + "}, " + "\"type\" : 2," + "\"pcc_rule\" : [" + "{" + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2d\" }," + "\"qos\" : {" + "\"qci\" : 1," + "\"gbr\" : {" + "\"downlink\" : { \"$numberLong\" : \"64\" }," + "\"uplink\" : { \"$numberLong\" : \"44\" }" + "}," + "\"mbr\" : {" + "\"downlink\" : { \"$numberLong\" : \"64\" }," + "\"uplink\" : { \"$numberLong\" : \"44\" }" + "}," + "\"arp\" : {" + "\"priority_level\" : 3," + "\"pre_emption_vulnerability\" : 0," + "\"pre_emption_capability\" : 0 }" + "}," + "\"flow\" : [" + "{ \"direction\" : 2," + "\"description\" : \"permit out udp from 10.200.136.98/32 23454 to assigned 1-65535\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } }," + "{ \"direction\" : 1," + "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to assigned 50020\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } }," + "{ \"direction\" : 2," + "\"description\" : \"permit out udp from 10.200.136.98/32 23455 to assigned 1-65535\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } }," + "{ \"direction\" : 1," + "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to assigned 50021\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }" + "]" + "}" + "]" + "}" + "]," + "\"security\" : { " + "\"k\" : \"70d49a71dd1a2b806a25abe0ef749f1e\", " + "\"opc\" : \"6f1bf53d624b3a43af6592854e2444c7\", " + "\"amf\" : \"8000\", " + "\"sqn\" : { \"$numberLong\" : \"25235952177090\" } " + "}, " + "\"subscribed_rau_tau_timer\" : 12," + "\"network_access_mode\" : 2, " + "\"subscriber_status\" : 0, " + "\"access_restriction_data\" : 32, " + "\"__v\" : 0 " + "}"; + + /* Setup Test UE & Session Context */ + memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci)); + + mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI; + mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI; + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0; + mobile_identity_suci.scheme_output[1] = 0; + mobile_identity_suci.scheme_output[2] = 0x20; + mobile_identity_suci.scheme_output[3] = 0x31; + mobile_identity_suci.scheme_output[4] = 0x90; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->nr_cgi.cell_id = 0x40001; + + test_ue->nas.registration.type = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.registration.follow_on_request = 1; + test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL; + + OGS_HEX(_k_string, strlen(_k_string), test_ue->k); + OGS_HEX(_opc_string, strlen(_opc_string), test_ue->opc); + + sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5); + ogs_assert(sess); + + /* Two gNB connects to AMF */ + ngap1 = testngap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, ngap1); + + ngap2 = testngap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, ngap2); + + /* Two gNB connects to UPF */ + gtpu1 = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu1); + + gtpu2 = test_gtpu_server(2, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu2); + + /* NG-Setup Reqeust/Response for Source gNB */ + sendbuf = testngap_build_ng_setup_request(0x4000, 28); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* NG-Setup Reqeust/Response for Target gNB */ + sendbuf = testngap_build_ng_setup_request(0x4001, 28); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap2, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + recvbuf = testgnb_ngap_read(ngap2); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /********** Insert Subscriber in Database */ + collection = mongoc_client_get_collection( + ogs_mongoc()->client, ogs_mongoc()->name, "subscribers"); + ABTS_PTR_NOTNULL(tc, collection); + doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); + ABTS_PTR_NOTNULL(tc, doc); + + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + if (count) { + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + } + bson_destroy(doc); + + doc = bson_new_from_json((const uint8_t *)json, -1, &error);; + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_insert(collection, + MONGOC_INSERT_NONE, doc, NULL, &error)); + bson_destroy(doc); + + doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); + ABTS_PTR_NOTNULL(tc, doc); + do { + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + } while (count == 0); + bson_destroy(doc); + + /* Send Registration request */ + test_ue->registration_request_param.guti = 1; + gmmbuf = testgmm_build_registration_request(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + test_ue->registration_request_param.gmm_capability = 1; + test_ue->registration_request_param.requested_nssai = 1; + test_ue->registration_request_param.last_visited_registered_tai = 1; + test_ue->registration_request_param.ue_usage_setting = 1; + nasbuf = testgmm_build_registration_request(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, nasbuf); + + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, false); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Identity request */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Identity response */ + gmmbuf = testgmm_build_identity_response(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication request */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + gmmbuf = testgmm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode command */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + gmmbuf = testgmm_build_security_mode_complete(test_ue, nasbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial context setup request */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send UE radio capability info indication */ + sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial context setup response */ + sendbuf = testngap_build_initial_context_setup_response(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Registration complete */ + gmmbuf = testgmm_build_registration_complete(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Configuration update command */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send PDU session establishment request */ + sess->ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + sess->ul_nas_transport_param.dnn = 1; + sess->ul_nas_transport_param.s_nssai = 1; + + gsmbuf = testgsm_build_pdu_session_establishment_request(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive PDU session establishment accept */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 1); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDU session resource setup response */ + sendbuf = testngap_build_pdu_session_resource_setup_response(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive PDU session modification command */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send PDU session resource modify response */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 2); + ogs_assert(qos_flow); + + sendbuf = testngap_build_pdu_session_resource_modify_response(qos_flow); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDU session resource modify complete */ + sess->ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_MODIFICATION_REQUEST; + sess->ul_nas_transport_param.dnn = 0; + sess->ul_nas_transport_param.s_nssai = 0; + + gsmbuf = testgsm_build_pdu_session_modification_complete(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Waiting for creating dedicated QoS flow in PFCP protocol */ + ogs_msleep(100); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Path Switch Request */ + test_ue->nr_cgi.cell_id = 0x40002; + test_ue->ran_ue_ngap_id++; + sess->gnb_n3_addr = test_self()->gnb2_addr; + + sendbuf = testngap_build_path_switch_request(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap2, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive End Mark */ + recvbuf = test_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive End Mark */ + recvbuf = test_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive Path Switch Ack */ + recvbuf = testgnb_ngap_read(ngap2); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 1); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu2, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu2); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 2); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu2, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu2); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send Path Switch Request */ + test_ue->nr_cgi.cell_id = 0x40001; + test_ue->ran_ue_ngap_id++; + sess->gnb_n3_addr = test_self()->gnb1_addr; + + sendbuf = testngap_build_path_switch_request(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive End Mark */ + recvbuf = test_gtpu_read(gtpu2); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive End Mark */ + recvbuf = test_gtpu_read(gtpu2); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive Path Switch Ack */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 1); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 2); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu1); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send UE context release request */ + sendbuf = testngap_build_ue_context_release_request(test_ue, + NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity, + true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE context release command */ + recvbuf = testgnb_ngap_read(ngap1); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send UE context release complete */ + sendbuf = testngap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap1, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + bson_destroy(doc); + + mongoc_collection_destroy(collection); + + /* Two gNB disonncect from UPF */ + testgnb_gtpu_close(gtpu1); + testgnb_gtpu_close(gtpu2); + + /* Two gNB disonncect from AMF */ + testgnb_ngap_close(ngap1); + testgnb_ngap_close(ngap2); + + /* Clear Test UE Context */ + test_ue_remove(test_ue); +} + +abts_suite *test_5gc_xn(abts_suite *suite) +{ + suite = ADD_SUITE(suite) + + abts_run_test(suite, test1_func, NULL); + + return suite; +} diff --git a/tests/handover/abts-main.c b/tests/handover/abts-main.c index 276dec61d..23853a494 100644 --- a/tests/handover/abts-main.c +++ b/tests/handover/abts-main.c @@ -21,12 +21,14 @@ abts_suite *test_epc_x2(abts_suite *suite); abts_suite *test_epc_s1(abts_suite *suite); +abts_suite *test_5gc_xn(abts_suite *suite); const struct testlist { abts_suite *(*func)(abts_suite *suite); } alltests[] = { {test_epc_x2}, {test_epc_s1}, + {test_5gc_xn}, {NULL}, }; diff --git a/tests/handover/epc-x2-test.c b/tests/handover/epc-x2-test.c index 3fb8eab4c..6ad4420b2 100644 --- a/tests/handover/epc-x2-test.c +++ b/tests/handover/epc-x2-test.c @@ -155,7 +155,7 @@ static void test1_func(abts_case *tc, void *data) s1ap2 = tests1ap_client(AF_INET); ABTS_PTR_NOTNULL(tc, s1ap2); - /* eNB connects to SGW */ + /* Two eNB connects to SGW */ gtpu1 = test_gtpu_server(1, AF_INET); ABTS_PTR_NOTNULL(tc, gtpu1); @@ -368,6 +368,7 @@ static void test1_func(abts_case *tc, void *data) /* Send Path Switch Request */ test_ue->e_cgi.cell_id = 0x461530; + test_ue->enb_ue_s1ap_id++; ogs_list_for_each(&sess->bearer_list, bearer) { bearer->enb_s1u_addr = test_self()->gnb2_addr; bearer->enb_s1u_addr6 = test_self()->gnb2_addr6; @@ -375,11 +376,11 @@ static void test1_func(abts_case *tc, void *data) sendbuf = test_s1ap_build_path_switch_request(test_ue); ABTS_PTR_NOTNULL(tc, sendbuf); - rv = testenb_s1ap_send(s1ap1, sendbuf); + rv = testenb_s1ap_send(s1ap2, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Receive Path Switch Ack */ - recvbuf = testenb_s1ap_read(s1ap1); + recvbuf = testenb_s1ap_read(s1ap2); ABTS_PTR_NOTNULL(tc, recvbuf); tests1ap_recv(test_ue, recvbuf); @@ -433,6 +434,16 @@ static void test1_func(abts_case *tc, void *data) ABTS_PTR_NOTNULL(tc, recvbuf); tests1ap_recv(test_ue, recvbuf); + /* Receive End Mark */ + recvbuf = test_gtpu_read(gtpu2); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive End Mark */ + recvbuf = test_gtpu_read(gtpu2); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + /* Send GTP-U ICMP Packet */ bearer = test_bearer_find_by_ue_ebi(test_ue, 5); ogs_assert(bearer); @@ -464,9 +475,9 @@ static void test1_func(abts_case *tc, void *data) mongoc_collection_destroy(collection); - /* eNB disonncect from SGW */ - testgnb_gtpu_close(gtpu2); + /* Two eNB disonncect from SGW */ testgnb_gtpu_close(gtpu1); + testgnb_gtpu_close(gtpu2); /* Two eNB disonncect from MME */ testenb_s1ap_close(s1ap1); diff --git a/tests/handover/meson.build b/tests/handover/meson.build index a1056441b..8dabbc40d 100644 --- a/tests/handover/meson.build +++ b/tests/handover/meson.build @@ -19,6 +19,7 @@ testapp_handover_sources = files(''' abts-main.c epc-x2-test.c epc-s1-test.c + 5gc-xn-test.c '''.split()) testapp_handover_exe = executable('handover', diff --git a/tests/minimal/minimal-test.c b/tests/minimal/minimal-test.c index 3f6215497..7af899f64 100644 --- a/tests/minimal/minimal-test.c +++ b/tests/minimal/minimal-test.c @@ -112,7 +112,7 @@ static void test1_func(abts_case *tc, void *data) test_ue->nr_cgi.cell_id = 0x40001; - test_ue->nas.registration.type = 1; + test_ue->nas.registration.type = 0; test_ue->nas.registration.follow_on_request = 1; test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL; diff --git a/tests/vonr/qos-flow-test.c b/tests/vonr/qos-flow-test.c index aeb7ff3a6..1ea904981 100644 --- a/tests/vonr/qos-flow-test.c +++ b/tests/vonr/qos-flow-test.c @@ -343,11 +343,10 @@ static void test1_func(abts_case *tc, void *data) ABTS_PTR_NOTNULL(tc, recvbuf); testngap_recv(test_ue, recvbuf); - /* Send GTP-U ICMP Packet */ + /* Send PDU session resource modify response */ qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 2); ogs_assert(qos_flow); - /* Send PDU session resource modify response */ sendbuf = testngap_build_pdu_session_resource_modify_response(qos_flow); ABTS_PTR_NOTNULL(tc, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);