diff --git a/lib/gtp/v1/types.c b/lib/gtp/v1/types.c index 92907d994..aabfb25e4 100644 --- a/lib/gtp/v1/types.c +++ b/lib/gtp/v1/types.c @@ -143,9 +143,9 @@ static uint32_t dec_mbr_kbps(uint8_t mbr_byte, const uint8_t *extended_mbr_byte, return (256 + embr2 * 4) * 1000; } if (embr1 >= 0xbb && embr1 <= 0xfa) - return (128 + (embr1 - (0xbb - 1)) * 1000) * 1000; + return (128 + (embr1 - (0xbb - 1)) * 2) * 1000; if (embr1 >= 0x4b && embr1 <= 0xba) - return (16 + (embr1 - (0x4b - 1)) * 100) * 1000; + return (16 + (embr1 - (0x4b - 1)) * 1) * 1000; return 8600 + embr1 * 100; } if (mbr & 0x80) { @@ -383,17 +383,17 @@ int16_t ogs_gtp1_build_qos_profile(ogs_tlv_octet_t *octet, /* Finally, set len based on the required octets to encode the fields: */ if (extended_ul == 2) - octet->len = 23; - else if (extended_dl == 2) octet->len = 21; - else if (extended_ul == 1) + else if (extended_dl == 2) octet->len = 19; - else if (extended_dl == 1) + else if (extended_ul == 1) octet->len = 17; - else if (decoded->data_octet14_present) + else if (extended_dl == 1) octet->len = 15; + else if (decoded->data_octet14_present) + octet->len = 13; else if (decoded->data_octet6_to_13_present) - octet->len = 14; + octet->len = 12; else octet->len = 6; return octet->len; diff --git a/src/smf/gn-build.c b/src/smf/gn-build.c index 4f80e591c..8593f4038 100644 --- a/src/smf/gn-build.c +++ b/src/smf/gn-build.c @@ -24,7 +24,8 @@ #include "ipfw/ipfw2.h" /* 3GPP TS 23.401 Annex E */ -static void build_qos_profile_from_session(ogs_gtp1_qos_profile_decoded_t *qos_pdec, const smf_sess_t *sess) +static void build_qos_profile_from_session(ogs_gtp1_qos_profile_decoded_t *qos_pdec, + const smf_sess_t *sess, const smf_bearer_t *bearer) { memset(qos_pdec, 0, sizeof(*qos_pdec)); @@ -99,6 +100,8 @@ static void build_qos_profile_from_session(ogs_gtp1_qos_profile_decoded_t *qos_p qos_pdec->data_octet14_present = true; qos_pdec->dec_mbr_kbps_dl = sess->session.ambr.downlink / 1000; qos_pdec->dec_mbr_kbps_ul = sess->session.ambr.uplink / 1000; + qos_pdec->dec_gbr_kbps_dl = bearer->qos.gbr.downlink / 1000; + qos_pdec->dec_gbr_kbps_ul = bearer->qos.gbr.uplink / 1000; } ogs_pkbuf_t *smf_gn_build_create_pdp_context_response( @@ -245,7 +248,7 @@ ogs_pkbuf_t *smf_gn_build_create_pdp_context_response( /* QoS Profile: if PCRF changes Bearer QoS, this should be included. */ if (sess->gtp.create_session_response_bearer_qos == true) { - build_qos_profile_from_session(&qos_pdec, sess); + build_qos_profile_from_session(&qos_pdec, sess, bearer); rsp->quality_of_service_profile.presence = 1; ogs_gtp1_build_qos_profile(&rsp->quality_of_service_profile, &qos_pdec, qos_pdec_buf, OGS_GTP1_QOS_PROFILE_MAX_LEN); @@ -434,7 +437,7 @@ ogs_pkbuf_t *smf_gn_build_update_pdp_context_response( /* QoS Profile: if PCRF changes Bearer QoS, this should be included. */ if (sess->gtp.create_session_response_bearer_qos == true) { - build_qos_profile_from_session(&qos_pdec, sess); + build_qos_profile_from_session(&qos_pdec, sess, bearer); rsp->quality_of_service_profile.presence = 1; ogs_gtp1_build_qos_profile(&rsp->quality_of_service_profile, &qos_pdec, qos_pdec_buf, OGS_GTP1_QOS_PROFILE_MAX_LEN); diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index b89929421..3498f4296 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -253,6 +253,14 @@ uint8_t smf_gn_handle_create_pdp_context_request( ogs_assert(rv == OGS_OK); ogs_debug(" SGW_S5U_TEID[0x%x] PGW_S5U_TEID[0x%x]", bearer->sgw_s5u_teid, bearer->pgw_s5u_teid); + if (qos_pdec.data_octet6_to_13_present) { + bearer->qos.gbr.downlink = qos_pdec.dec_gbr_kbps_dl * 1000; + bearer->qos.gbr.uplink = qos_pdec.dec_gbr_kbps_ul * 1000; + } else { + /* Set some sane default if infomation not present in Qos Profile IE: */ + bearer->qos.gbr.downlink = sess->session.ambr.downlink; + bearer->qos.gbr.uplink = sess->session.ambr.uplink; + } /* Select PGW based on UE Location Information */ smf_sess_select_upf(sess);