forked from acouzens/open5gs
feat: Add 5G Core Xn Handover (#726)
This commit is contained in:
parent
b329b09573
commit
70a7bac6b2
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
* Copyright (C) 2019,2020 by Lester Lee <lishihui19821@gmail.com>
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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},
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue