diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 1ea56b75c..3517ff496 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -67,7 +67,7 @@ services: volumes: - home:/home/${USER} - ${HOME}:/mnt - - /tmp/.X11-unix:/tmp/.X11-unix + # - /tmp/.X11-unix:/tmp/.X11-unix # - /etc/localtime:/etc/localtime:ro # - /usr/share/zoneinfo/Europe/Helsinki:/etc/localtime:ro hostname: open5gs-dev diff --git a/src/sgwc/sxa-handler.c b/src/sgwc/sxa-handler.c index 36154bd4c..a5704d384 100644 --- a/src/sgwc/sxa-handler.c +++ b/src/sgwc/sxa-handler.c @@ -448,8 +448,6 @@ void sgwc_sxa_handle_session_modification_response( ogs_gtp2_cause_t cause; - OGS_LIST(pdr_to_create_list); - ogs_debug("Session Modification Response"); ogs_assert(pfcp_xact); @@ -507,6 +505,8 @@ void sgwc_sxa_handle_session_modification_response( ogs_pfcp_pdr_t *pdr = NULL; ogs_pfcp_far_t *far = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(sess); ogs_list_copy(&pdr_to_create_list, &pfcp_xact->pdr_to_create_list); @@ -938,9 +938,14 @@ void sgwc_sxa_handle_session_modification_response( } } else if (flags & OGS_PFCP_MODIFY_ACTIVATE) { + OGS_LIST(bearer_to_modify_list); + s11_xact = pfcp_xact->assoc_xact; ogs_assert(s11_xact); + ogs_list_copy(&bearer_to_modify_list, + &pfcp_xact->bearer_to_modify_list); + ogs_pfcp_xact_commit(pfcp_xact); ogs_assert(flags & OGS_PFCP_MODIFY_SESSION); @@ -968,7 +973,8 @@ void sgwc_sxa_handle_session_modification_response( /* Send Data Plane(UL) : SGW-S1U */ i = 0; - ogs_list_for_each(&sess->bearer_list, bearer) { + ogs_list_for_each_entry( + &bearer_to_modify_list, bearer, to_modify_node) { ogs_assert(i < OGS_BEARER_PER_UE); ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer); diff --git a/src/smf/binding.c b/src/smf/binding.c index b76082e36..035a826ed 100644 --- a/src/smf/binding.c +++ b/src/smf/binding.c @@ -24,7 +24,7 @@ #include "ipfw/ipfw2.h" -static void bearer_timeout(ogs_gtp_xact_t *xact, void *data) +static void gtp_bearer_timeout(ogs_gtp_xact_t *xact, void *data) { smf_bearer_t *bearer = data; smf_sess_t *sess = NULL; @@ -234,12 +234,12 @@ void smf_bearer_binding(smf_sess_t *sess) } } - /* - * We only use the method of adding a flow to an existing tft. - * - * EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT - * 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS - */ + /* + * We only use the method of adding a flow to an existing tft. + * + * EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT + * 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS + */ ogs_list_init(&bearer->pf_to_add_list); for (j = 0; j < pcc_rule->num_of_flow; j++) { @@ -351,7 +351,7 @@ void smf_bearer_binding(smf_sess_t *sess) ogs_expect_or_return(pkbuf); xact = ogs_gtp_xact_local_create( - sess->gnode, &h, pkbuf, bearer_timeout, bearer); + sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer); ogs_expect_or_return(xact); if (ogs_list_count(&bearer->pf_to_add_list) > 0) @@ -413,13 +413,14 @@ int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer) h.teid = sess->sgw_s5c_teid; memset(&tft, 0, sizeof tft); - encode_traffic_flow_template(&tft, bearer, OGS_GTP2_TFT_CODE_CREATE_NEW_TFT); + encode_traffic_flow_template( + &tft, bearer, OGS_GTP2_TFT_CODE_CREATE_NEW_TFT); pkbuf = smf_s5c_build_create_bearer_request(h.type, bearer, &tft); ogs_expect_or_return_val(pkbuf, OGS_ERROR); xact = ogs_gtp_xact_local_create( - sess->gnode, &h, pkbuf, bearer_timeout, bearer); + sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer); ogs_expect_or_return_val(xact, OGS_ERROR); rv = ogs_gtp_xact_commit(xact); @@ -433,8 +434,14 @@ void smf_qos_flow_binding(smf_sess_t *sess) int rv; int i, j; + uint64_t pfcp_flags, check; + ogs_assert(sess); + pfcp_flags = OGS_PFCP_MODIFY_NETWORK_REQUESTED; + + ogs_list_init(&sess->qos_flow_to_modify_list); + for (i = 0; i < sess->policy.num_of_pcc_rule; i++) { smf_bearer_t *qos_flow = NULL; ogs_pcc_rule_t *pcc_rule = &sess->policy.pcc_rule[i]; @@ -521,12 +528,12 @@ void smf_qos_flow_binding(smf_sess_t *sess) } } - /* - * We only use the method of adding a flow to an existing tft. - * - * EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT - * 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS - */ + /* + * We only use the method of adding a flow to an existing tft. + * + * EPC: OGS_GTP2_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT + * 5GC: OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS + */ ogs_list_init(&qos_flow->pf_to_add_list); for (j = 0; j < pcc_rule->num_of_flow; j++) { @@ -609,15 +616,11 @@ void smf_qos_flow_binding(smf_sess_t *sess) smf_bearer_tft_update(qos_flow); smf_bearer_qos_update(qos_flow); - ogs_assert(OGS_OK == - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, NULL, - OGS_PFCP_MODIFY_NETWORK_REQUESTED| - OGS_PFCP_MODIFY_CREATE)); + pfcp_flags |= OGS_PFCP_MODIFY_CREATE; + ogs_list_add(&sess->qos_flow_to_modify_list, + &qos_flow->to_modify_node); } else { - uint64_t pfcp_flags = 0; - pfcp_flags |= OGS_PFCP_MODIFY_NETWORK_REQUESTED; if (ogs_list_count(&qos_flow->pf_to_add_list) > 0) { @@ -629,9 +632,8 @@ void smf_qos_flow_binding(smf_sess_t *sess) smf_bearer_qos_update(qos_flow); } - ogs_assert(OGS_OK == - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, NULL, pfcp_flags)); + ogs_list_add(&sess->qos_flow_to_modify_list, + &qos_flow->to_modify_node); } } else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) { qos_flow = smf_qos_flow_find_by_pcc_rule_id(sess, pcc_rule->id); @@ -643,14 +645,27 @@ void smf_qos_flow_binding(smf_sess_t *sess) continue; } - ogs_assert(OGS_OK == - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, NULL, - OGS_PFCP_MODIFY_NETWORK_REQUESTED|OGS_PFCP_MODIFY_REMOVE)); + pfcp_flags |= OGS_PFCP_MODIFY_REMOVE; + + ogs_list_add(&sess->qos_flow_to_modify_list, + &qos_flow->to_modify_node); } else { ogs_error("Invalid Type[%d]", pcc_rule->type); ogs_assert_if_reached(); } } + + check = pfcp_flags & (OGS_PFCP_MODIFY_CREATE|OGS_PFCP_MODIFY_REMOVE); + if (check != 0 && + check != OGS_PFCP_MODIFY_CREATE && check != OGS_PFCP_MODIFY_REMOVE) { + ogs_fatal("Invalid flags[%ld]", pfcp_flags); + ogs_assert_if_reached(); + } + + if (ogs_list_count(&sess->qos_flow_to_modify_list)) { + ogs_assert(OGS_OK == + smf_5gc_pfcp_send_session_modification_request( + sess, NULL, pfcp_flags, 0)); + } } diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index 94cbf4d0b..d554e6ff0 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -418,7 +418,7 @@ void smf_gn_handle_update_pdp_context_request( } } - rv = smf_epc_pfcp_send_session_modification_request(sess, xact, NULL, + rv = smf_epc_pfcp_send_pdr_modification_request(sess, xact, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP1_CAUSE_REACTIACTION_REQUESTED); diff --git a/src/smf/gsm-build.c b/src/smf/gsm-build.c index 970d222aa..ace4cb58a 100644 --- a/src/smf/gsm-build.c +++ b/src/smf/gsm-build.c @@ -291,14 +291,14 @@ static void encode_qos_rule_packet_filter( } } -ogs_pkbuf_t *gsm_build_qos_flow_modification_command( - smf_bearer_t *qos_flow, uint8_t pti, +ogs_pkbuf_t *gsm_build_pdu_session_modification_command( + smf_sess_t *sess, uint8_t pti, uint8_t qos_rule_code, uint8_t qos_flow_description_code) { ogs_pkbuf_t *pkbuf = NULL; - smf_sess_t *sess = NULL; + smf_bearer_t *qos_flow = NULL; ogs_pfcp_pdr_t *dl_pdr = NULL; - int num_of_param, rv; + int num_of_param, rv, i; ogs_nas_5gs_message_t message; ogs_nas_5gs_pdu_session_modification_command_t @@ -319,11 +319,7 @@ ogs_pkbuf_t *gsm_build_qos_flow_modification_command( &pdu_session_modification_command->authorized_qos_flow_descriptions; ogs_assert(authorized_qos_flow_descriptions); - ogs_assert(qos_flow); - sess = qos_flow->sess; ogs_assert(sess); - dl_pdr = qos_flow->dl_pdr; - ogs_assert(dl_pdr); memset(&message, 0, sizeof(message)); message.gsm.h.extended_protocol_discriminator = @@ -334,26 +330,39 @@ ogs_pkbuf_t *gsm_build_qos_flow_modification_command( /* QoS rule */ if (qos_rule_code) { + + i = 0; memset(qos_rule, 0, sizeof(qos_rule)); - qos_rule[0].identifier = qos_flow->qfi; /* Use QFI in Open5GS */ - qos_rule[0].code = qos_rule_code; - if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE && - qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) - encode_qos_rule_packet_filter(&qos_rule[0], qos_flow); + ogs_list_for_each_entry( + &sess->qos_flow_to_modify_list, qos_flow, to_modify_node) { + ogs_assert(i < OGS_MAX_NUM_OF_BEARER); - if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE && - qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS && - qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) { - ogs_assert(dl_pdr->precedence > 0 && dl_pdr->precedence < 255); - /* Use PCC Rule Precedence */ - qos_rule[0].precedence = dl_pdr->precedence; + dl_pdr = qos_flow->dl_pdr; + ogs_assert(dl_pdr); - qos_rule[0].flow.segregation = 0; - qos_rule[0].flow.identifier = qos_flow->qfi; + qos_rule[i].identifier = qos_flow->qfi; /* Use QFI in Open5GS */ + qos_rule[i].code = qos_rule_code; + + if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE && + qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) + encode_qos_rule_packet_filter(&qos_rule[i], qos_flow); + + if (qos_rule_code != OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE && + qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS && + qos_rule_code != OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_WITHOUT_MODIFYING_PACKET_FILTERS) { + ogs_assert(dl_pdr->precedence > 0 && dl_pdr->precedence < 255); + /* Use PCC Rule Precedence */ + qos_rule[i].precedence = dl_pdr->precedence; + + qos_rule[i].flow.segregation = 0; + qos_rule[i].flow.identifier = qos_flow->qfi; + } + + i++; } - rv = ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, 1); + rv = ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, i); ogs_expect_or_return_val(rv == OGS_OK, NULL); ogs_expect_or_return_val(authorized_qos_rules->length, NULL); @@ -363,69 +372,81 @@ ogs_pkbuf_t *gsm_build_qos_flow_modification_command( /* QoS flow descriptions */ if (qos_flow_description_code) { + + i = 0; memset(&qos_flow_description, 0, sizeof(qos_flow_description)); - qos_flow_description[0].identifier = qos_flow->qfi; - qos_flow_description[0].code = qos_flow_description_code; - num_of_param = 0; + ogs_list_for_each_entry( + &sess->qos_flow_to_modify_list, qos_flow, to_modify_node) { + ogs_assert(i < OGS_MAX_NUM_OF_BEARER); - if (qos_flow_description_code != OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION) { - qos_flow_description[0].E_bit = 1; + qos_flow_description[i].identifier = qos_flow->qfi; + qos_flow_description[i].code = qos_flow_description_code; - qos_flow_description[0].param[num_of_param].identifier = - OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI; - qos_flow_description[0].param[num_of_param].len = - sizeof(qos_flow_description[0].param[num_of_param].qos_index); - qos_flow_description[0].param[num_of_param].qos_index = - qos_flow->qos.index; - num_of_param++; + num_of_param = 0; - if (qos_flow->qos.gbr.uplink) { - qos_flow_description[0].param[num_of_param].identifier = - OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK; - qos_flow_description[0].param[num_of_param].len = - sizeof(qos_flow_description[0].param[num_of_param].br); - ogs_nas_bitrate_from_uint64( - &qos_flow_description[0].param[num_of_param].br, - qos_flow->qos.gbr.uplink); - num_of_param++; - } - if (qos_flow->qos.gbr.downlink) { - qos_flow_description[0].param[num_of_param].identifier = - OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK; - qos_flow_description[0].param[num_of_param].len = - sizeof(qos_flow_description[0].param[num_of_param].br); - ogs_nas_bitrate_from_uint64( - &qos_flow_description[0].param[num_of_param].br, - qos_flow->qos.gbr.downlink); - num_of_param++; - } - if (qos_flow->qos.mbr.uplink) { - qos_flow_description[0].param[num_of_param].identifier = - OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK; - qos_flow_description[0].param[num_of_param].len = - sizeof(qos_flow_description[0].param[num_of_param].br); - ogs_nas_bitrate_from_uint64( - &qos_flow_description[0].param[num_of_param].br, - qos_flow->qos.mbr.uplink); - num_of_param++; - } - if (qos_flow->qos.mbr.downlink) { - qos_flow_description[0].param[num_of_param].identifier = - OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK; - qos_flow_description[0].param[num_of_param].len = - sizeof(qos_flow_description[0].param[num_of_param].br); - ogs_nas_bitrate_from_uint64( - &qos_flow_description[0].param[num_of_param].br, - qos_flow->qos.mbr.downlink); + if (qos_flow_description_code != + OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION) { + qos_flow_description[i].E_bit = 1; + + qos_flow_description[i].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI; + qos_flow_description[i].param[num_of_param].len = + sizeof(qos_flow_description[i].param[num_of_param]. + qos_index); + qos_flow_description[i].param[num_of_param].qos_index = + qos_flow->qos.index; num_of_param++; + + if (qos_flow->qos.gbr.uplink) { + qos_flow_description[i].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK; + qos_flow_description[i].param[num_of_param].len = + sizeof(qos_flow_description[i].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[i].param[num_of_param].br, + qos_flow->qos.gbr.uplink); + num_of_param++; + } + if (qos_flow->qos.gbr.downlink) { + qos_flow_description[i].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK; + qos_flow_description[i].param[num_of_param].len = + sizeof(qos_flow_description[i].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[i].param[num_of_param].br, + qos_flow->qos.gbr.downlink); + num_of_param++; + } + if (qos_flow->qos.mbr.uplink) { + qos_flow_description[i].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK; + qos_flow_description[i].param[num_of_param].len = + sizeof(qos_flow_description[i].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[i].param[num_of_param].br, + qos_flow->qos.mbr.uplink); + num_of_param++; + } + if (qos_flow->qos.mbr.downlink) { + qos_flow_description[i].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK; + qos_flow_description[i].param[num_of_param].len = + sizeof(qos_flow_description[i].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[i].param[num_of_param].br, + qos_flow->qos.mbr.downlink); + num_of_param++; + } } + + qos_flow_description[i].num_of_parameter = num_of_param; + + i++; } - qos_flow_description[0].num_of_parameter = num_of_param; - rv = ogs_nas_build_qos_flow_descriptions( - authorized_qos_flow_descriptions, qos_flow_description, 1); + authorized_qos_flow_descriptions, qos_flow_description, i); ogs_expect_or_return_val(rv == OGS_OK, NULL); ogs_expect_or_return_val( authorized_qos_flow_descriptions->length, NULL); diff --git a/src/smf/gsm-build.h b/src/smf/gsm-build.h index 7adcf2062..6df396d56 100644 --- a/src/smf/gsm-build.h +++ b/src/smf/gsm-build.h @@ -30,8 +30,8 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess); ogs_pkbuf_t *gsm_build_pdu_session_establishment_reject( smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause); -ogs_pkbuf_t *gsm_build_qos_flow_modification_command( - smf_bearer_t *qos_flow, uint8_t pti, +ogs_pkbuf_t *gsm_build_pdu_session_modification_command( + smf_sess_t *sess, uint8_t pti, uint8_t qos_rule_code, uint8_t qos_flow_description_code); ogs_pkbuf_t *gsm_build_pdu_session_modification_reject( smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause); diff --git a/src/smf/gsm-handler.c b/src/smf/gsm-handler.c index 3054fc04c..a91f9304d 100644 --- a/src/smf/gsm-handler.c +++ b/src/smf/gsm-handler.c @@ -195,7 +195,7 @@ int gsm_handle_pdu_session_modification_request( int i, j; uint64_t pfcp_flags = 0; - ogs_list_t update_list, delete_list; + smf_bearer_t *qos_flow = NULL; smf_pf_t *pf = NULL; @@ -217,8 +217,7 @@ int gsm_handle_pdu_session_modification_request( ogs_assert(stream); ogs_assert(pdu_session_modification_request); - ogs_list_init(&update_list); - ogs_list_init(&delete_list); + ogs_list_init(&sess->qos_flow_to_modify_list); if (pdu_session_modification_request->presencemask & OGS_NAS_5GS_PDU_SESSION_MODIFICATION_REQUEST_5GSM_CAUSE_PRESENT) { @@ -246,7 +245,8 @@ int gsm_handle_pdu_session_modification_request( smf_pf_remove_all(qos_flow); pfcp_flags |= OGS_PFCP_MODIFY_REMOVE; - qos_flow_find_or_add(&delete_list, qos_flow, to_delete_node); + qos_flow_find_or_add(&sess->qos_flow_to_modify_list, + qos_flow, to_modify_node); } else if (qos_rule[i].code == OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS) { for (j = 0; j < qos_rule[i].num_of_packet_filter && @@ -306,8 +306,8 @@ int gsm_handle_pdu_session_modification_request( } pfcp_flags |= OGS_PFCP_MODIFY_TFT_REPLACE; - qos_flow_find_or_add( - &update_list, qos_flow, to_modify_node); + qos_flow_find_or_add(&sess->qos_flow_to_modify_list, + qos_flow, to_modify_node); ogs_list_add( &qos_flow->pf_to_add_list, &pf->to_add_node); @@ -388,8 +388,8 @@ int gsm_handle_pdu_session_modification_request( } else ogs_assert_if_reached(); - qos_flow_find_or_add( - &update_list, qos_flow, to_modify_node); + qos_flow_find_or_add(&sess->qos_flow_to_modify_list, + qos_flow, to_modify_node); ogs_list_add( &qos_flow->pf_to_add_list, &pf->to_add_node); @@ -413,12 +413,12 @@ int gsm_handle_pdu_session_modification_request( if (ogs_list_count(&qos_flow->pf_list)) { pfcp_flags |= OGS_PFCP_MODIFY_TFT_DELETE; - qos_flow_find_or_add( - &update_list, qos_flow, to_modify_node); + qos_flow_find_or_add(&sess->qos_flow_to_modify_list, + qos_flow, to_modify_node); } else { pfcp_flags |= OGS_PFCP_MODIFY_REMOVE; - qos_flow_find_or_add( - &delete_list, qos_flow, to_delete_node); + qos_flow_find_or_add(&sess->qos_flow_to_modify_list, + qos_flow, to_modify_node); } } } @@ -469,14 +469,15 @@ int gsm_handle_pdu_session_modification_request( } pfcp_flags |= OGS_PFCP_MODIFY_QOS_MODIFY; - qos_flow_find_or_add(&update_list, qos_flow, to_modify_node); + qos_flow_find_or_add(&sess->qos_flow_to_modify_list, + qos_flow, to_modify_node); } } - if ((ogs_list_count(&update_list) + ogs_list_count(&delete_list)) != 1) { + if (ogs_list_count(&sess->qos_flow_to_modify_list) != 1) { strerror = ogs_msprintf("[%s:%d] Invalid modification request " - "[update:%d,delete:%d]", smf_ue->supi, sess->psi, - ogs_list_count(&update_list), ogs_list_count(&delete_list)); + "[modify:%d]", smf_ue->supi, sess->psi, + ogs_list_count(&sess->qos_flow_to_modify_list)); ogs_assert(strerror); ogs_error("%s", strerror); @@ -492,20 +493,19 @@ int gsm_handle_pdu_session_modification_request( return OGS_ERROR; } - ogs_assert(qos_flow); - if (pfcp_flags & OGS_PFCP_MODIFY_REMOVE) { - - ogs_assert(OGS_OK == - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, stream, - OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags)); + ogs_assert((pfcp_flags & + (OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD| + OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE| + OGS_PFCP_MODIFY_QOS_MODIFY)) == 0); } else if (pfcp_flags & (OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD| OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE| OGS_PFCP_MODIFY_QOS_MODIFY)) { + ogs_assert((pfcp_flags & OGS_PFCP_MODIFY_REMOVE) == 0); + if (pfcp_flags & (OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD| OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE)) @@ -514,13 +514,15 @@ int gsm_handle_pdu_session_modification_request( if (pfcp_flags & OGS_PFCP_MODIFY_QOS_MODIFY) smf_bearer_qos_update(qos_flow); - ogs_assert(OGS_OK == - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, stream, OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags)); } else { ogs_fatal("Unknown PFCP-Flags : [0x%llx]", (long long)pfcp_flags); ogs_assert_if_reached(); } + ogs_assert(OGS_OK == + smf_5gc_pfcp_send_session_modification_request( + sess, stream, + OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags, 0)); + return OGS_OK; } diff --git a/src/smf/gy-handler.c b/src/smf/gy-handler.c index cfd978f24..e8a703802 100644 --- a/src/smf/gy-handler.c +++ b/src/smf/gy-handler.c @@ -174,7 +174,7 @@ void smf_gy_handle_cca_update_request( /* Send PFCP Session Modification Request if we need to update the params. */ if (modify_flags) { modify_flags |= OGS_PFCP_MODIFY_URR|OGS_PFCP_MODIFY_UL_ONLY; - rv = smf_epc_pfcp_send_session_modification_request( + rv = smf_epc_pfcp_send_pdr_modification_request( sess, pfcp_xact, NULL, modify_flags, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP1_CAUSE_REACTIACTION_REQUESTED); diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 33f63e536..5fef8a3f1 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -265,7 +265,7 @@ void smf_5gc_n4_handle_session_modification_response( stream = xact->assoc_stream; if (flags & OGS_PFCP_MODIFY_SESSION) { - /* If smf_5gc_pfcp_send_session_modification_request() is called */ + /* If smf_5gc_pfcp_send_pdr_modification_request() is called */ } else { /* If smf_5gc_pfcp_send_qos_flow_modification_request() is called */ @@ -390,7 +390,7 @@ void smf_5gc_n4_handle_session_modification_response( if (smf_sess_have_indirect_data_forwarding(sess) == true) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE, ogs_app()->time.handover.duration)); @@ -444,7 +444,7 @@ void smf_5gc_n4_handle_session_modification_response( smf_sess_create_indirect_data_forwarding(sess); ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE, 0)); @@ -454,47 +454,57 @@ void smf_5gc_n4_handle_session_modification_response( } } else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) { smf_n1_n2_message_transfer_param_t param; + smf_bearer_t *next = NULL; - ogs_assert(qos_flow); + ogs_assert(flags & OGS_PFCP_MODIFY_SESSION); memset(¶m, 0, sizeof(param)); param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION; - param.n1smbuf = gsm_build_qos_flow_modification_command( - qos_flow, + param.n1smbuf = gsm_build_pdu_session_modification_command( + sess, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE, OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION); ogs_assert(param.n1smbuf); param.n2smbuf = - ngap_build_qos_flow_resource_release_request_transfer( - qos_flow, + ngap_build_pdu_session_resource_release_request_transfer( + sess, NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release); ogs_assert(param.n2smbuf); smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m); - smf_bearer_remove(qos_flow); + ogs_list_for_each_entry_safe(&sess->qos_flow_to_modify_list, + next, qos_flow, to_modify_node) + smf_bearer_remove(qos_flow); + } else if (flags & OGS_PFCP_MODIFY_UE_REQUESTED) { ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL; + smf_bearer_t *next = NULL; ogs_assert(stream); - ogs_assert(qos_flow); - n1smbuf = gsm_build_qos_flow_modification_command( - qos_flow, sess->pti, + ogs_assert(flags & OGS_PFCP_MODIFY_SESSION); + + n1smbuf = gsm_build_pdu_session_modification_command( + sess, sess->pti, OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE, OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION); ogs_assert(n1smbuf); - n2smbuf = ngap_build_qos_flow_resource_release_request_transfer( - qos_flow, + n2smbuf = ngap_build_pdu_session_resource_release_request_transfer( + sess, NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release); ogs_assert(n2smbuf); - smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream, - n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_MOD_REQ, n2smbuf); + smf_sbi_send_sm_context_updated_data_n1_n2_message( + sess, stream, n1smbuf, + OpenAPI_n2_sm_info_type_PDU_RES_MOD_REQ, n2smbuf); + + ogs_list_for_each_entry_safe(&sess->qos_flow_to_modify_list, + next, qos_flow, to_modify_node) + smf_bearer_remove(qos_flow); - smf_bearer_remove(qos_flow); } else { ogs_fatal("Unknown flags [0x%llx]", (long long)flags); ogs_assert_if_reached(); @@ -511,22 +521,23 @@ void smf_5gc_n4_handle_session_modification_response( } else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) { smf_n1_n2_message_transfer_param_t param; - ogs_assert(qos_flow); + ogs_assert(flags & OGS_PFCP_MODIFY_SESSION); memset(¶m, 0, sizeof(param)); param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION; - param.n1smbuf = gsm_build_qos_flow_modification_command( - qos_flow, + param.n1smbuf = gsm_build_pdu_session_modification_command( + sess, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE, OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION); ogs_assert(param.n1smbuf); param.n2smbuf = - ngap_build_qos_flow_resource_modify_request_transfer( - qos_flow, true); + ngap_build_pdu_session_resource_modify_request_transfer( + sess, true); ogs_assert(param.n2smbuf); smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m); + } else { ogs_fatal("Unknown flags [0x%llx]", (long long)flags); ogs_assert_if_reached(); @@ -559,35 +570,36 @@ void smf_5gc_n4_handle_session_modification_response( } if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) { - ogs_assert(qos_flow); + ogs_assert(flags & OGS_PFCP_MODIFY_SESSION); memset(¶m, 0, sizeof(param)); param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION; - param.n1smbuf = gsm_build_qos_flow_modification_command( - qos_flow, + param.n1smbuf = gsm_build_pdu_session_modification_command( + sess, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, qos_rule_code, qos_flow_description_code); ogs_assert(param.n1smbuf); param.n2smbuf = - ngap_build_qos_flow_resource_modify_request_transfer( - qos_flow, - (flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false); + ngap_build_pdu_session_resource_modify_request_transfer( + sess, + (flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false); ogs_assert(param.n2smbuf); smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m); + } else if (flags & OGS_PFCP_MODIFY_UE_REQUESTED) { ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL; ogs_assert(stream); - ogs_assert(qos_flow); - n1smbuf = gsm_build_qos_flow_modification_command( - qos_flow, sess->pti, + ogs_assert(flags & OGS_PFCP_MODIFY_SESSION); + n1smbuf = gsm_build_pdu_session_modification_command( + sess, sess->pti, qos_rule_code, qos_flow_description_code); ogs_assert(n1smbuf); - n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer( - qos_flow, + n2smbuf = ngap_build_pdu_session_resource_modify_request_transfer( + sess, (flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false); ogs_assert(n2smbuf); @@ -794,7 +806,7 @@ void smf_epc_n4_handle_session_modification_response( ogs_debug("Session Modification Response [epc]"); if (flags & OGS_PFCP_MODIFY_SESSION) { - /* If smf_epc_pfcp_send_session_modification_request() is called */ + /* If smf_epc_pfcp_send_pdr_modification_request() is called */ } else { /* If smf_epc_pfcp_send_bearer_modification_request() is called */ bearer = xact->data; @@ -1207,7 +1219,7 @@ void smf_n4_handle_session_report_request( if (error_indication_session) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( error_indication_session, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE| OGS_PFCP_MODIFY_ERROR_INDICATION, diff --git a/src/smf/ngap-build.c b/src/smf/ngap-build.c index 27b02b98c..69843c6f9 100644 --- a/src/smf/ngap-build.c +++ b/src/smf/ngap-build.c @@ -199,8 +199,8 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, &message); } -ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( - smf_bearer_t *qos_flow, bool qos_presence) +ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request_transfer( + smf_sess_t *sess, bool qos_presence) { NGAP_PDUSessionResourceModifyRequestTransfer_t message; @@ -215,7 +215,9 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( NGAP_AllocationAndRetentionPriority_t *allocationAndRetentionPriority; NGAP_GBR_QosInformation_t *gBR_QosInformation; - ogs_assert(qos_flow); + smf_bearer_t *qos_flow = NULL; + + ogs_assert(sess); ogs_debug("PDUSessionResourceModifyRequestTransfer"); memset(&message, 0, sizeof(NGAP_PDUSessionResourceModifyRequestTransfer_t)); @@ -229,66 +231,70 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( QosFlowAddOrModifyRequestList = &ie->value.choice.QosFlowAddOrModifyRequestList; - QosFlowAddOrModifyRequestItem = - CALLOC(1, sizeof(*QosFlowAddOrModifyRequestItem)); - ASN_SEQUENCE_ADD(&QosFlowAddOrModifyRequestList->list, QosFlowAddOrModifyRequestItem); + ogs_list_for_each_entry( + &sess->qos_flow_to_modify_list, qos_flow, to_modify_node) { - qosFlowIdentifier = &QosFlowAddOrModifyRequestItem->qosFlowIdentifier; + QosFlowAddOrModifyRequestItem = + CALLOC(1, sizeof(*QosFlowAddOrModifyRequestItem)); + ASN_SEQUENCE_ADD(&QosFlowAddOrModifyRequestList->list, QosFlowAddOrModifyRequestItem); - QosFlowAddOrModifyRequestItem->qosFlowLevelQosParameters = - qosFlowLevelQosParameters = - CALLOC(1, sizeof(*qosFlowLevelQosParameters)); + qosFlowIdentifier = &QosFlowAddOrModifyRequestItem->qosFlowIdentifier; - allocationAndRetentionPriority = - &qosFlowLevelQosParameters->allocationAndRetentionPriority; - qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics; + QosFlowAddOrModifyRequestItem->qosFlowLevelQosParameters = + qosFlowLevelQosParameters = + CALLOC(1, sizeof(*qosFlowLevelQosParameters)); - qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI; - qosCharacteristics->choice.nonDynamic5QI = - nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor)); + allocationAndRetentionPriority = + &qosFlowLevelQosParameters->allocationAndRetentionPriority; + qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics; - *qosFlowIdentifier = qos_flow->qfi; + qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI; + qosCharacteristics->choice.nonDynamic5QI = + nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor)); - nonDynamic5QI->fiveQI = qos_flow->qos.index; + *qosFlowIdentifier = qos_flow->qfi; - allocationAndRetentionPriority->priorityLevelARP = - qos_flow->qos.arp.priority_level; - if (qos_flow->qos.arp.pre_emption_capability == - OGS_5GC_PRE_EMPTION_ENABLED) - allocationAndRetentionPriority->pre_emptionCapability = - NGAP_Pre_emptionCapability_may_trigger_pre_emption; - if (qos_flow->qos.arp.pre_emption_vulnerability == - OGS_5GC_PRE_EMPTION_ENABLED) - allocationAndRetentionPriority->pre_emptionVulnerability = - NGAP_Pre_emptionVulnerability_pre_emptable; + nonDynamic5QI->fiveQI = qos_flow->qos.index; - if (qos_presence == true && - (qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink || - qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink)) { - ogs_assert(qos_flow->qos.mbr.downlink); - ogs_assert(qos_flow->qos.mbr.uplink); - ogs_assert(qos_flow->qos.gbr.downlink); - ogs_assert(qos_flow->qos.gbr.uplink); + allocationAndRetentionPriority->priorityLevelARP = + qos_flow->qos.arp.priority_level; + if (qos_flow->qos.arp.pre_emption_capability == + OGS_5GC_PRE_EMPTION_ENABLED) + allocationAndRetentionPriority->pre_emptionCapability = + NGAP_Pre_emptionCapability_may_trigger_pre_emption; + if (qos_flow->qos.arp.pre_emption_vulnerability == + OGS_5GC_PRE_EMPTION_ENABLED) + allocationAndRetentionPriority->pre_emptionVulnerability = + NGAP_Pre_emptionVulnerability_pre_emptable; - qosFlowLevelQosParameters->gBR_QosInformation = - gBR_QosInformation = CALLOC(1, sizeof(*gBR_QosInformation)); + if (qos_presence == true && + (qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink || + qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink)) { + ogs_assert(qos_flow->qos.mbr.downlink); + ogs_assert(qos_flow->qos.mbr.uplink); + ogs_assert(qos_flow->qos.gbr.downlink); + ogs_assert(qos_flow->qos.gbr.uplink); - asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateDL, - qos_flow->qos.mbr.downlink); - asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateUL, - qos_flow->qos.mbr.uplink); - asn_uint642INTEGER(&gBR_QosInformation-> - guaranteedFlowBitRateDL, qos_flow->qos.gbr.downlink); - asn_uint642INTEGER(&gBR_QosInformation-> - guaranteedFlowBitRateUL, qos_flow->qos.gbr.uplink); + qosFlowLevelQosParameters->gBR_QosInformation = + gBR_QosInformation = CALLOC(1, sizeof(*gBR_QosInformation)); + + asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateDL, + qos_flow->qos.mbr.downlink); + asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateUL, + qos_flow->qos.mbr.uplink); + asn_uint642INTEGER(&gBR_QosInformation-> + guaranteedFlowBitRateDL, qos_flow->qos.gbr.downlink); + asn_uint642INTEGER(&gBR_QosInformation-> + guaranteedFlowBitRateUL, qos_flow->qos.gbr.uplink); + } } return ogs_asn_encode( &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, &message); } -ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer( - smf_bearer_t *qos_flow, NGAP_Cause_PR group, long cause) +ogs_pkbuf_t *ngap_build_pdu_session_resource_release_request_transfer( + smf_sess_t *sess, NGAP_Cause_PR group, long cause) { NGAP_PDUSessionResourceModifyRequestTransfer_t message; @@ -299,7 +305,9 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer( NGAP_QosFlowIdentifier_t *qosFlowIdentifier = NULL; NGAP_Cause_t *Cause = NULL; - ogs_assert(qos_flow); + smf_bearer_t *qos_flow = NULL; + + ogs_assert(sess); ogs_debug("PDUSessionResourceModifyRequestTransfer"); memset(&message, 0, sizeof(NGAP_PDUSessionResourceModifyRequestTransfer_t)); @@ -313,16 +321,21 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer( QosFlowListWithCause = &ie->value.choice.QosFlowListWithCause; - QosFlowWithCauseItem = CALLOC(1, sizeof(*QosFlowWithCauseItem)); - ASN_SEQUENCE_ADD(&QosFlowListWithCause->list, QosFlowWithCauseItem); + ogs_list_for_each_entry( + &sess->qos_flow_to_modify_list, qos_flow, to_modify_node) { - qosFlowIdentifier = &QosFlowWithCauseItem->qosFlowIdentifier; + QosFlowWithCauseItem = CALLOC(1, sizeof(*QosFlowWithCauseItem)); + ASN_SEQUENCE_ADD(&QosFlowListWithCause->list, QosFlowWithCauseItem); - *qosFlowIdentifier = qos_flow->qfi; + qosFlowIdentifier = &QosFlowWithCauseItem->qosFlowIdentifier; - Cause = &QosFlowWithCauseItem->cause; - Cause->present = group; - Cause->choice.radioNetwork = cause; + *qosFlowIdentifier = qos_flow->qfi; + + Cause = &QosFlowWithCauseItem->cause; + Cause->present = group; + Cause->choice.radioNetwork = cause; + + } return ogs_asn_encode( &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, &message); diff --git a/src/smf/ngap-build.h b/src/smf/ngap-build.h index e6ec80e87..31adff3c0 100644 --- a/src/smf/ngap-build.h +++ b/src/smf/ngap-build.h @@ -29,11 +29,10 @@ extern "C" { ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( smf_sess_t *sess); -ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( - smf_bearer_t *qos_flow, bool qos_presence); - -ogs_pkbuf_t *ngap_build_qos_flow_resource_release_request_transfer( - smf_bearer_t *qos_flow, NGAP_Cause_PR group, long cause); +ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request_transfer( + smf_sess_t *sess, bool qos_presence); +ogs_pkbuf_t *ngap_build_pdu_session_resource_release_request_transfer( + smf_sess_t *sess, NGAP_Cause_PR group, long cause); ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer( smf_sess_t *sess, int state, NGAP_Cause_PR group, long cause); diff --git a/src/smf/ngap-handler.c b/src/smf/ngap-handler.c index 84d6f9369..0f2f1ff9e 100644 --- a/src/smf/ngap-handler.c +++ b/src/smf/ngap-handler.c @@ -147,7 +147,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( if (far_update) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, 0)); } else { @@ -247,7 +247,7 @@ int ngap_handle_pdu_session_resource_setup_unsuccessful_transfer( */ ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, 0)); @@ -304,6 +304,8 @@ int ngap_handle_pdu_session_resource_modify_response_transfer( goto cleanup; } + ogs_list_init(&sess->qos_flow_to_modify_list); + if (qosFlowAddOrModifyResponseList) { for (i = 0; i < qosFlowAddOrModifyResponseList->list.count; i++) { NGAP_QosFlowAddOrModifyResponseItem_t @@ -315,11 +317,26 @@ int ngap_handle_pdu_session_resource_modify_response_transfer( if (qosFlowAddOrModifyResponseItem) { qos_flow = smf_qos_flow_find_by_qfi(sess, qosFlowAddOrModifyResponseItem->qosFlowIdentifier); + if (qos_flow) { + dl_far = qos_flow->dl_far; + ogs_assert(dl_far); + + dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; + ogs_assert(OGS_OK == + 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; + + ogs_list_add(&sess->qos_flow_to_modify_list, + &qos_flow->to_modify_node); + } } } } - if (!qos_flow) { + if (ogs_list_count(&sess->qos_flow_to_modify_list) == 0) { 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, @@ -327,20 +344,10 @@ int ngap_handle_pdu_session_resource_modify_response_transfer( goto cleanup; } - dl_far = qos_flow->dl_far; - ogs_assert(dl_far); - - dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; ogs_assert(OGS_OK == - 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; - - ogs_assert(OGS_OK == - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, stream, OGS_PFCP_MODIFY_ACTIVATE)); + smf_5gc_pfcp_send_session_modification_request( + sess, stream, + OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, 0)); rv = OGS_OK; @@ -467,7 +474,7 @@ int ngap_handle_path_switch_request_transfer( if (far_update) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE| OGS_PFCP_MODIFY_XN_HANDOVER|OGS_PFCP_MODIFY_END_MARKER, @@ -676,7 +683,7 @@ int ngap_handle_handover_request_ack( ogs_error("It will be automatically removed"); ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT| /* @@ -698,7 +705,7 @@ int ngap_handle_handover_request_ack( smf_sess_create_indirect_data_forwarding(sess); ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE, 0)); diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c index 5ca4aa8eb..44d1eba99 100644 --- a/src/smf/nsmf-handler.c +++ b/src/smf/nsmf-handler.c @@ -370,7 +370,7 @@ bool smf_nsmf_handle_update_sm_context( sess, stream, OpenAPI_up_cnx_state_DEACTIVATED); } else { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, 0)); } @@ -506,7 +506,7 @@ bool smf_nsmf_handle_update_sm_context( if (far_update) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE| OGS_PFCP_MODIFY_N2_HANDOVER|OGS_PFCP_MODIFY_END_MARKER, @@ -539,7 +539,7 @@ bool smf_nsmf_handle_update_sm_context( if (smf_sess_have_indirect_data_forwarding(sess) == true) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE| OGS_PFCP_MODIFY_HANDOVER_CANCEL, diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 2e9321f00..39513dd99 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -19,7 +19,6 @@ #include "sbi-path.h" #include "pfcp-path.h" -#include "n4-build.h" static void pfcp_node_fsm_init(ogs_pfcp_node_t *node, bool try_to_assoicate) { @@ -215,45 +214,6 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data) } } -static void qos_flow_5gc_timeout(ogs_pfcp_xact_t *xact, void *data) -{ - smf_ue_t *smf_ue = NULL; - smf_sess_t *sess = NULL; - smf_bearer_t *qos_flow = NULL; - ogs_sbi_stream_t *stream = NULL; - uint8_t type; - char *strerror = NULL; - - ogs_assert(xact); - ogs_assert(data); - - qos_flow = data; - ogs_assert(qos_flow); - sess = qos_flow->sess; - ogs_assert(sess); - smf_ue = sess->smf_ue; - ogs_assert(smf_ue); - - type = xact->seq[0].type; - switch (type) { - case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE: - strerror = ogs_msprintf("[%s:%d] No PFCP session modification response", - smf_ue->supi, sess->psi); - ogs_assert(strerror); - - ogs_error("%s", strerror); - if (stream) - smf_sbi_send_sm_context_update_error(stream, - OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, - strerror, NULL, NULL, NULL); - ogs_free(strerror); - break; - default: - ogs_error("Not implemented [type:%d]", type); - break; - } -} - static void sess_epc_timeout(ogs_pfcp_xact_t *xact, void *data) { uint8_t type; @@ -367,6 +327,28 @@ int smf_5gc_pfcp_send_session_modification_request( { int rv; ogs_pfcp_xact_t *xact = NULL; + + ogs_assert(sess); + + xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess); + ogs_expect_or_return_val(xact, OGS_ERROR); + + xact->assoc_stream = stream; + xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; + + rv = smf_pfcp_send_modify_list( + sess, smf_n4_build_qos_flow_to_modify_list, xact, duration); + ogs_expect(rv == OGS_OK); + + return rv; +} + +int smf_5gc_pfcp_send_pdr_modification_request( + smf_sess_t *sess, ogs_sbi_stream_t *stream, + uint64_t flags, ogs_time_t duration) +{ + int rv; + ogs_pfcp_xact_t *xact = NULL; ogs_pfcp_pdr_t *pdr = NULL; ogs_assert(sess); @@ -390,34 +372,6 @@ int smf_5gc_pfcp_send_session_modification_request( return rv; } -int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow, - ogs_sbi_stream_t *stream, uint64_t flags) -{ - int rv; - ogs_pfcp_xact_t *xact = NULL; - smf_sess_t *sess = NULL; - - ogs_assert(qos_flow); - sess = qos_flow->sess; - ogs_assert(sess); - - xact = ogs_pfcp_xact_local_create( - sess->pfcp_node, qos_flow_5gc_timeout, qos_flow); - ogs_expect_or_return_val(xact, OGS_ERROR); - - xact->assoc_stream = stream; - xact->modify_flags = flags; - - ogs_list_init(&sess->qos_flow_to_modify_list); - ogs_list_add(&sess->qos_flow_to_modify_list, &qos_flow->to_modify_node); - - rv = smf_pfcp_send_modify_list( - sess, smf_n4_build_qos_flow_to_modify_list, xact, 0); - ogs_expect(rv == OGS_OK); - - return rv; -} - int smf_5gc_pfcp_send_session_deletion_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger) { @@ -484,16 +438,17 @@ int smf_epc_pfcp_send_session_establishment_request( } int smf_epc_pfcp_send_session_modification_request( - smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf, - uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause) + smf_sess_t *sess, void *gtp_xact, + uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause, + ogs_time_t duration) { int rv; ogs_pfcp_xact_t *xact = NULL; - ogs_pfcp_pdr_t *pdr = NULL; ogs_assert(sess); - xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess); + xact = ogs_pfcp_xact_local_create( + sess->pfcp_node, sess_epc_timeout, sess); ogs_expect_or_return_val(xact, OGS_ERROR); xact->epc = true; /* EPC PFCP transaction */ @@ -502,17 +457,9 @@ int smf_epc_pfcp_send_session_modification_request( xact->gtp_pti = gtp_pti; xact->gtp_cause = gtp_cause; - if (gtpbuf) { - xact->gtpbuf = ogs_pkbuf_copy(gtpbuf); - ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR); - } - - ogs_list_init(&sess->pdr_to_modify_list); - ogs_list_for_each(&sess->pfcp.pdr_list, pdr) - ogs_list_add(&sess->pdr_to_modify_list, &pdr->to_modify_node); rv = smf_pfcp_send_modify_list( - sess, smf_n4_build_pdr_to_modify_list, xact, 0); + sess, smf_n4_build_qos_flow_to_modify_list, xact, duration); ogs_expect(rv == OGS_OK); return rv; @@ -551,6 +498,41 @@ int smf_epc_pfcp_send_bearer_modification_request( return rv; } +int smf_epc_pfcp_send_pdr_modification_request( + smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf, + uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause) +{ + int rv; + ogs_pfcp_xact_t *xact = NULL; + ogs_pfcp_pdr_t *pdr = NULL; + + ogs_assert(sess); + + xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess); + ogs_expect_or_return_val(xact, OGS_ERROR); + + xact->epc = true; /* EPC PFCP transaction */ + xact->assoc_xact = gtp_xact; + xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; + + xact->gtp_pti = gtp_pti; + xact->gtp_cause = gtp_cause; + if (gtpbuf) { + xact->gtpbuf = ogs_pkbuf_copy(gtpbuf); + ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR); + } + + ogs_list_init(&sess->pdr_to_modify_list); + ogs_list_for_each(&sess->pfcp.pdr_list, pdr) + ogs_list_add(&sess->pdr_to_modify_list, &pdr->to_modify_node); + + rv = smf_pfcp_send_modify_list( + sess, smf_n4_build_pdr_to_modify_list, xact, 0); + ogs_expect(rv == OGS_OK); + + return rv; +} + int smf_epc_pfcp_send_session_deletion_request( smf_sess_t *sess, void *gtp_xact) { @@ -625,7 +607,7 @@ int smf_epc_pfcp_send_deactivation(smf_sess_t *sess, uint8_t gtp_cause) ogs_list_first(&wlan_sess->bearer_list), OGS_ERROR); /* Deactivate WLAN Session */ - rv = smf_epc_pfcp_send_session_modification_request( + rv = smf_epc_pfcp_send_pdr_modification_request( wlan_sess, NULL, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, @@ -642,7 +624,7 @@ int smf_epc_pfcp_send_deactivation(smf_sess_t *sess, uint8_t gtp_cause) ogs_list_first(&eutran_sess->bearer_list), OGS_ERROR); /* Deactivate EUTRAN Session */ - rv = smf_epc_pfcp_send_session_modification_request( + rv = smf_epc_pfcp_send_pdr_modification_request( eutran_sess, NULL, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, diff --git a/src/smf/pfcp-path.h b/src/smf/pfcp-path.h index 8f2545b1c..37f8efeb5 100644 --- a/src/smf/pfcp-path.h +++ b/src/smf/pfcp-path.h @@ -20,7 +20,7 @@ #ifndef SMF_PFCP_PATH_H #define SMF_PFCP_PATH_H -#include "ogs-gtp.h" +#include "n4-build.h" #ifdef __cplusplus extern "C" { @@ -40,20 +40,24 @@ int smf_5gc_pfcp_send_session_establishment_request( int smf_5gc_pfcp_send_session_modification_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, uint64_t flags, ogs_time_t duration); -int smf_5gc_pfcp_send_qos_flow_modification_request( - smf_bearer_t *qos_flow, ogs_sbi_stream_t *stream, - uint64_t flags); +int smf_5gc_pfcp_send_pdr_modification_request( + smf_sess_t *sess, ogs_sbi_stream_t *stream, + uint64_t flags, ogs_time_t duration); int smf_5gc_pfcp_send_session_deletion_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger); int smf_epc_pfcp_send_session_establishment_request( smf_sess_t *sess, void *gtp_xact); int smf_epc_pfcp_send_session_modification_request( - smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf, - uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause); + smf_sess_t *sess, void *gtp_xact, + uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause, + ogs_time_t duration); int smf_epc_pfcp_send_bearer_modification_request( smf_bearer_t *bearer, void *gtp_xact, uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause); +int smf_epc_pfcp_send_pdr_modification_request( + smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf, + uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause); int smf_epc_pfcp_send_session_deletion_request( smf_sess_t *sess, void *gtp_xact); diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 70b83b1bf..cbce269e4 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -27,6 +27,29 @@ #include "ipfw/ipfw2.h" +static void pfcp_sess_timeout(ogs_pfcp_xact_t *xact, void *data) +{ + uint8_t type; + + ogs_assert(xact); + type = xact->seq[0].type; + + switch (type) { + case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE: + ogs_error("No PFCP session establishment response"); + break; + case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE: + ogs_error("No PFCP session modification response"); + break; + case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE: + ogs_error("No PFCP session deletion response"); + break; + default: + ogs_error("Not implemented [type:%d]", type); + break; + } +} + void smf_s5c_handle_echo_request( ogs_gtp_xact_t *xact, ogs_gtp2_echo_request_t *req) { @@ -394,7 +417,7 @@ uint8_t smf_s5c_handle_delete_session_request( } void smf_s5c_handle_modify_bearer_request( - smf_sess_t *sess, ogs_gtp_xact_t *xact, + smf_sess_t *sess, ogs_gtp_xact_t *gtp_xact, ogs_pkbuf_t *gtpbuf, ogs_gtp2_modify_bearer_request_t *req) { int rv, i; @@ -406,7 +429,7 @@ void smf_s5c_handle_modify_bearer_request( ogs_debug("Modify Bearer Request"); - ogs_assert(xact); + ogs_assert(gtp_xact); ogs_assert(req); /************************ @@ -420,7 +443,7 @@ void smf_s5c_handle_modify_bearer_request( } if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0, + ogs_gtp2_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0, OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value); return; } @@ -441,7 +464,7 @@ void smf_s5c_handle_modify_bearer_request( rv = ogs_gtp2_f_teid_to_ip(sgw_s5c_teid, &sess->sgw_s5c_ip); ogs_assert(rv == OGS_OK); - OGS_SETUP_GTP_NODE(sess, xact->gnode); + OGS_SETUP_GTP_NODE(sess, gtp_xact->gnode); ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]", sess->sgw_s5c_teid, sess->smf_n4_teid); @@ -519,13 +542,27 @@ void smf_s5c_handle_modify_bearer_request( } if (ogs_list_count(&sess->qos_flow_to_modify_list)) { + ogs_pfcp_xact_t *pfcp_xact = NULL; /* Need to modify SGW-S5U */ - rv = smf_epc_pfcp_send_session_modification_request(sess, xact, gtpbuf, - flags|OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, - OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, - OGS_GTP2_CAUSE_UNDEFINED_VALUE); - ogs_assert(rv == OGS_OK); + pfcp_xact = ogs_pfcp_xact_local_create( + sess->pfcp_node, pfcp_sess_timeout, sess); + ogs_assert(pfcp_xact); + + pfcp_xact->epc = true; /* EPC PFCP transaction */ + pfcp_xact->assoc_xact = gtp_xact; + pfcp_xact->modify_flags = + flags|OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE; + + pfcp_xact->gtp_pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; + pfcp_xact->gtp_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE; + + ogs_assert(gtpbuf); + pfcp_xact->gtpbuf = ogs_pkbuf_copy(gtpbuf); + ogs_assert(pfcp_xact->gtpbuf); + + ogs_assert(OGS_OK == smf_pfcp_send_modify_list( + sess, smf_n4_build_qos_flow_to_modify_list, pfcp_xact, 0)); } else { @@ -533,7 +570,7 @@ void smf_s5c_handle_modify_bearer_request( ogs_gtp2_indication_t *indication = NULL; ogs_assert(OGS_OK == - smf_gtp2_send_modify_bearer_response(sess, xact, req, false)); + smf_gtp2_send_modify_bearer_response(sess, gtp_xact, req, false)); if (req->indication_flags.presence && req->indication_flags.data && req->indication_flags.len) { diff --git a/tests/common/context.h b/tests/common/context.h index 387620dde..5481defd1 100644 --- a/tests/common/context.h +++ b/tests/common/context.h @@ -459,11 +459,16 @@ typedef struct test_sess_s { ogs_list_t bearer_list; + ogs_list_t qos_flow_to_modify_list; + test_ue_t *test_ue; } test_sess_t; typedef struct test_bearer_s { ogs_lnode_t lnode; /**< A node of list_t */ + + ogs_lnode_t to_modify_node; + uint32_t index; uint8_t qfi; /* 5GC */ diff --git a/tests/common/ngap-build.c b/tests/common/ngap-build.c index df7a35ed8..71712785c 100644 --- a/tests/common/ngap-build.c +++ b/tests/common/ngap-build.c @@ -23,8 +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_setup_unsuccessful_trasfer( test_sess_t *sess, NGAP_Cause_PR group, long cause); -static ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response_trasfer( - test_bearer_t *qos_flow); +static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer( + test_sess_t *sess); static ogs_pkbuf_t *testngap_build_qos_flow_resource_release_response_trasfer( test_bearer_t *qos_flow); static ogs_pkbuf_t *testngap_build_path_switch_request_trasfer( @@ -1165,13 +1165,12 @@ ogs_pkbuf_t *testngap_sess_build_pdu_session_resource_failed_to_setup( return ogs_ngap_encode(&pdu); } -ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response( - test_bearer_t *qos_flow) +ogs_pkbuf_t *testngap_sess_build_pdu_session_resource_modify_response( + test_sess_t *sess) { int rv; test_ue_t *test_ue = NULL; - test_sess_t *sess = NULL; ogs_pkbuf_t *n2smbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL; @@ -1187,8 +1186,6 @@ ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response( NGAP_PDUSessionResourceModifyItemModRes_t *PDUSessionItem = NULL; OCTET_STRING_t *transfer = NULL; - ogs_assert(qos_flow); - sess = qos_flow->sess; ogs_assert(sess); test_ue = sess->test_ue; ogs_assert(test_ue); @@ -1245,8 +1242,7 @@ ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response( PDUSessionItem->pDUSessionID = sess->psi; - n2smbuf = testngap_build_qos_flow_resource_modify_response_trasfer( - qos_flow); + n2smbuf = testngap_build_pdu_session_resource_modify_response_trasfer(sess); ogs_assert(n2smbuf); transfer = &PDUSessionItem->pDUSessionResourceModifyResponseTransfer; @@ -1258,6 +1254,22 @@ ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response( return ogs_ngap_encode(&pdu); } +ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response( + test_bearer_t *qos_flow) +{ + int rv; + test_sess_t *sess = NULL; + + ogs_assert(qos_flow); + sess = qos_flow->sess; + ogs_assert(sess); + + ogs_list_init(&sess->qos_flow_to_modify_list); + ogs_list_add(&sess->qos_flow_to_modify_list, &qos_flow->to_modify_node); + + return testngap_sess_build_pdu_session_resource_modify_response(sess); +} + ogs_pkbuf_t *testngap_build_qos_flow_resource_release_response( test_bearer_t *qos_flow) { @@ -2377,27 +2389,34 @@ static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_unsuccessful_trasf &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, &message); } -static ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response_trasfer( - test_bearer_t *qos_flow) +static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer( + test_sess_t *sess) { - ogs_assert(qos_flow); - NGAP_PDUSessionResourceModifyResponseTransfer_t message; NGAP_QosFlowAddOrModifyResponseList_t *qosFlowAddOrModifyResponseList; NGAP_QosFlowAddOrModifyResponseItem_t *qosFlowAddOrModifyResponseItem; + test_bearer_t *qos_flow = NULL; + + ogs_assert(sess); + memset(&message, 0, sizeof(message)); message.qosFlowAddOrModifyResponseList = qosFlowAddOrModifyResponseList = CALLOC(1, sizeof(struct NGAP_QosFlowAddOrModifyResponseList)); - qosFlowAddOrModifyResponseItem = - CALLOC(1, sizeof(struct NGAP_QosFlowAddOrModifyResponseItem)); - ASN_SEQUENCE_ADD(&qosFlowAddOrModifyResponseList->list, - qosFlowAddOrModifyResponseItem); - qosFlowAddOrModifyResponseItem->qosFlowIdentifier = qos_flow->qfi; + ogs_list_for_each_entry( + &sess->qos_flow_to_modify_list, qos_flow, to_modify_node) { + + qosFlowAddOrModifyResponseItem = + CALLOC(1, sizeof(struct NGAP_QosFlowAddOrModifyResponseItem)); + ASN_SEQUENCE_ADD(&qosFlowAddOrModifyResponseList->list, + qosFlowAddOrModifyResponseItem); + + qosFlowAddOrModifyResponseItem->qosFlowIdentifier = qos_flow->qfi; + } return ogs_asn_encode( &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, &message); diff --git a/tests/common/ngap-build.h b/tests/common/ngap-build.h index 0b5efde9a..d73520605 100644 --- a/tests/common/ngap-build.h +++ b/tests/common/ngap-build.h @@ -51,6 +51,8 @@ ogs_pkbuf_t *testngap_sess_build_pdu_session_resource_setup_response( test_sess_t *sess); ogs_pkbuf_t *testngap_sess_build_pdu_session_resource_failed_to_setup( test_sess_t *sess, NGAP_Cause_PR group, long cause); +ogs_pkbuf_t *testngap_sess_build_pdu_session_resource_modify_response( + test_sess_t *sess); ogs_pkbuf_t *testngap_build_qos_flow_resource_modify_response( test_bearer_t *qos_flow); ogs_pkbuf_t *testngap_build_qos_flow_resource_release_response( diff --git a/tests/vonr/video-test.c b/tests/vonr/video-test.c index 70b183418..1a902011c 100644 --- a/tests/vonr/video-test.c +++ b/tests/vonr/video-test.c @@ -323,52 +323,18 @@ static void test1_func(abts_case *tc, void *data) NGAP_ProcedureCode_id_PDUSessionResourceModify, test_ue->ngap_procedure_code); - /* Receive PDUSessionResourceModifyRequest + - * DL NAS transport + - * PDU session modification command */ - recvbuf = testgnb_ngap_read(ngap); - ABTS_PTR_NOTNULL(tc, recvbuf); - testngap_recv(test_ue, recvbuf); - ABTS_INT_EQUAL(tc, - NGAP_ProcedureCode_id_PDUSessionResourceModify, - test_ue->ngap_procedure_code); - /* Send PDU session resource modify response */ + ogs_list_init(&sess->qos_flow_to_modify_list); + qos_flow = test_qos_flow_find_by_qfi(sess, 2); ogs_assert(qos_flow); + ogs_list_add(&sess->qos_flow_to_modify_list, &qos_flow->to_modify_node); - sendbuf = testngap_build_qos_flow_resource_modify_response(qos_flow); - ABTS_PTR_NOTNULL(tc, sendbuf); - rv = testgnb_ngap_send(ngap, 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; - - sess->pdu_session_establishment_param.ssc_mode = 0; - sess->pdu_session_establishment_param.epco = 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(ngap, sendbuf); - ABTS_INT_EQUAL(tc, OGS_OK, rv); - - /* Wait for PDU session resource modify complete */ - ogs_msleep(100); - - /* Send PDU session resource modify response */ qos_flow = test_qos_flow_find_by_qfi(sess, 3); ogs_assert(qos_flow); + ogs_list_add(&sess->qos_flow_to_modify_list, &qos_flow->to_modify_node); - sendbuf = testngap_build_qos_flow_resource_modify_response(qos_flow); + sendbuf = testngap_sess_build_pdu_session_resource_modify_response(sess); ABTS_PTR_NOTNULL(tc, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv);