diff --git a/src/amf/context.c b/src/amf/context.c index f521cfe7c..ff0db9440 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -1755,6 +1755,19 @@ bool amf_pdu_res_setup_req_transfer_needed(amf_ue_t *amf_ue) return false; } +bool amf_handover_request_transfer_needed(amf_ue_t *amf_ue) +{ + amf_sess_t *sess = NULL; + + ogs_assert(amf_ue); + + ogs_list_for_each(&amf_ue->sess_list, sess) + if (sess->transfer.handover_request) + return true; + + return false; +} + int amf_find_served_tai(ogs_5gs_tai_t *nr_tai) { int i = 0, j = 0, k = 0; diff --git a/src/amf/context.h b/src/amf/context.h index d8ba4d58d..a5408999f 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -162,6 +162,7 @@ struct ran_ue_s { /* UE context */ bool ue_context_requested; bool initial_context_setup_request_sent; + bool ue_ambr_sent; /* Handover Info */ ran_ue_t *source_ue; @@ -698,6 +699,9 @@ int amf_sess_xact_state_count(amf_ue_t *amf_ue, int state); #define PDU_RES_SETUP_REQ_TRANSFER_NEEDED(__aMF) \ (amf_pdu_res_setup_req_transfer_needed(__aMF) == true) bool amf_pdu_res_setup_req_transfer_needed(amf_ue_t *amf_ue); +#define HANDOVER_REQUEST_TRANSFER_NEEDED(__aMF) \ + (amf_handover_request_transfer_needed(__aMF) == true) +bool amf_handover_request_transfer_needed(amf_ue_t *amf_ue); int amf_find_served_tai(ogs_5gs_tai_t *nr_tai); ogs_s_nssai_t *amf_find_s_nssai( diff --git a/src/amf/ngap-build.c b/src/amf/ngap-build.c index 2e40e0c61..6e25a1584 100644 --- a/src/amf/ngap-build.c +++ b/src/amf/ngap-build.c @@ -371,8 +371,17 @@ ogs_pkbuf_t *ngap_build_downlink_nas_transport( memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size); ogs_pkbuf_free(gmmbuf); - if (ue_ambr && (amf_ue->ue_ambr.downlink || amf_ue->ue_ambr.uplink)) { + /* + * TS 38.413 + * 8.6.2 Downlink NAS Transport + * 8.6.2.1. Successful Operation + * + * The UE Aggregate Maximum Bit Rate IE should be sent to the NG-RAN node + * if the AMF has not sent it previously + */ + if (ran_ue->ue_ambr_sent == false && ue_ambr) { ogs_assert(amf_ue); + ogs_assert(amf_ue->ue_ambr.downlink && amf_ue->ue_ambr.uplink); ie = CALLOC(1, sizeof(NGAP_DownlinkNASTransport_IEs_t)); ASN_SEQUENCE_ADD(&DownlinkNASTransport->protocolIEs, ie); @@ -389,6 +398,8 @@ ogs_pkbuf_t *ngap_build_downlink_nas_transport( asn_uint642INTEGER( &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, amf_ue->ue_ambr.downlink); + + ran_ue->ue_ambr_sent = true; } if (allowed_nssai) { @@ -497,7 +508,19 @@ ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request( RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; - if (amf_ue->ue_ambr.downlink || amf_ue->ue_ambr.uplink) { + /* + * + * 9.2.2. UE Context Management Messages + * 9.2.2.1. INITIAL CONTEXT SETUP REQUEST + * + * + * if PDUsessionResourceSetup + * + * SHOULD NOT CHECK PREVIOUSLY SENT + */ + if (PDU_RES_SETUP_REQ_TRANSFER_NEEDED(amf_ue) == true) { + ogs_assert(amf_ue->ue_ambr.downlink && amf_ue->ue_ambr.uplink); + ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie); @@ -513,6 +536,8 @@ ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request( asn_uint642INTEGER( &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, amf_ue->ue_ambr.downlink); + + ran_ue->ue_ambr_sent = true; } ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); @@ -803,7 +828,19 @@ ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request( RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; - if (amf_ue->ue_ambr.downlink || amf_ue->ue_ambr.uplink) { + /* + * + * 9.2.2. UE Context Management Messages + * 9.2.2.1. INITIAL CONTEXT SETUP REQUEST + * + *
+ * if PDUsessionResourceSetup + * + * SHOULD NOT CHECK PREVIOUSLY SENT + */ + if (gmmbuf || n2smbuf) { + ogs_assert(amf_ue->ue_ambr.downlink && amf_ue->ue_ambr.uplink); + ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie); @@ -820,6 +857,8 @@ ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request( asn_uint642INTEGER( &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, amf_ue->ue_ambr.downlink); + + ran_ue->ue_ambr_sent = true; } ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); @@ -1107,6 +1146,7 @@ ogs_pkbuf_t *ngap_ue_build_pdu_session_resource_setup_request( NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; NGAP_NAS_PDU_t *NAS_PDU = NULL; + NGAP_UEAggregateMaximumBitRate_t *UEAggregateMaximumBitRate = NULL; NGAP_PDUSessionResourceSetupListSUReq_t *PDUSessionList = NULL; NGAP_PDUSessionResourceSetupItemSUReq_t *PDUSessionItem = NULL; @@ -1217,6 +1257,37 @@ ogs_pkbuf_t *ngap_ue_build_pdu_session_resource_setup_request( ogs_assert(PDUSessionList); ogs_assert(PDUSessionList->list.count); + /* + * TS 38.413 + * 8.2.1. PDU Session Resource Setup + * 8.2.1.2. Successful Operation + * + * The UE Aggregate Maximum Bit Rate IE should be sent to the NG-RAN node + * if the AMF has not sent it previously. + */ + if (ran_ue->ue_ambr_sent == false && + PDU_RES_SETUP_REQ_TRANSFER_NEEDED(amf_ue) == true) { + ogs_assert(amf_ue->ue_ambr.downlink && amf_ue->ue_ambr.uplink); + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceSetupRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupRequestIEs__value_PR_UEAggregateMaximumBitRate; + + UEAggregateMaximumBitRate = &ie->value.choice.UEAggregateMaximumBitRate; + + asn_uint642INTEGER( + &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateUL, + amf_ue->ue_ambr.uplink); + asn_uint642INTEGER( + &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, + amf_ue->ue_ambr.downlink); + + ran_ue->ue_ambr_sent = true; + } + return ogs_ngap_encode(&pdu); } @@ -1241,6 +1312,8 @@ ogs_pkbuf_t *ngap_sess_build_pdu_session_resource_setup_request( NGAP_SST_t *sST = NULL; OCTET_STRING_t *transfer = NULL; + NGAP_UEAggregateMaximumBitRate_t *UEAggregateMaximumBitRate = NULL; + ogs_assert(n2smbuf); ogs_assert(sess); @@ -1330,6 +1403,36 @@ ogs_pkbuf_t *ngap_sess_build_pdu_session_resource_setup_request( memcpy(transfer->buf, n2smbuf->data, transfer->size); ogs_pkbuf_free(n2smbuf); + /* + * TS 38.413 + * 8.2.1. PDU Session Resource Setup + * 8.2.1.2. Successful Operation + * + * The UE Aggregate Maximum Bit Rate IE should be sent to the NG-RAN node + * if the AMF has not sent it previously. + */ + if (ran_ue->ue_ambr_sent == false) { + ogs_assert(amf_ue->ue_ambr.downlink && amf_ue->ue_ambr.uplink); + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceSetupRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupRequestIEs__value_PR_UEAggregateMaximumBitRate; + + UEAggregateMaximumBitRate = &ie->value.choice.UEAggregateMaximumBitRate; + + asn_uint642INTEGER( + &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateUL, + amf_ue->ue_ambr.uplink); + asn_uint642INTEGER( + &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, + amf_ue->ue_ambr.downlink); + + ran_ue->ue_ambr_sent = true; + } + return ogs_ngap_encode(&pdu); } @@ -1911,14 +2014,17 @@ ogs_pkbuf_t *ngap_build_handover_request(ran_ue_t *target_ue) ogs_debug(" Group[%d] Cause[%d]", Cause->present, (int)Cause->choice.radioNetwork); - if (amf_ue->ue_ambr.downlink || amf_ue->ue_ambr.uplink) { + if (HANDOVER_REQUEST_TRANSFER_NEEDED(amf_ue) == true) { + ogs_assert(amf_ue->ue_ambr.downlink && amf_ue->ue_ambr.uplink); + ie = CALLOC(1, sizeof(NGAP_HandoverRequestIEs_t)); ogs_assert(ie); ASN_SEQUENCE_ADD(&HandoverRequest->protocolIEs, ie); ie->id = NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate; ie->criticality = NGAP_Criticality_reject; - ie->value.present = NGAP_HandoverRequestIEs__value_PR_UEAggregateMaximumBitRate; + ie->value.present = + NGAP_HandoverRequestIEs__value_PR_UEAggregateMaximumBitRate; UEAggregateMaximumBitRate = &ie->value.choice.UEAggregateMaximumBitRate; @@ -1928,6 +2034,8 @@ ogs_pkbuf_t *ngap_build_handover_request(ran_ue_t *target_ue) asn_uint642INTEGER( &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, amf_ue->ue_ambr.downlink); + + target_ue->ue_ambr_sent = true; } ie = CALLOC(1, sizeof(NGAP_HandoverRequestIEs_t)); diff --git a/src/amf/ngap-path.c b/src/amf/ngap-path.c index 23fe87ffb..b08fd3879 100644 --- a/src/amf/ngap-path.c +++ b/src/amf/ngap-path.c @@ -466,6 +466,7 @@ void ngap_send_handover_request(amf_ue_t *amf_ue) ogs_assert(amf_ue); source_ue = amf_ue->ran_ue; ogs_assert(source_ue); + target_ue = source_ue->target_ue; ogs_assert(target_ue);