[MME] Handle Charging Characteristics

Found no support for HSS provided charging characteristics.  Following TS32.251 A.4:
- Use PDN level CC, if one wasn't provided then use subscription level CC
- Don't send CC in S11 if it wasn't included
This commit is contained in:
jmasterfunk84 2022-07-21 12:57:00 -06:00 committed by Sukchan Lee
parent d2ef555ce4
commit 68140efce4
7 changed files with 63 additions and 3 deletions

View File

@ -56,6 +56,8 @@ extern "C" {
#define OGS_PLMN_ID_LEN 3
#define OGS_MAX_PLMN_ID_BCD_LEN 6
#define OGS_CHRGCHARS_LEN 2
#define OGS_BCD_TO_BUFFER_LEN(x) (((x)+1)/2)
#define OGS_MAX_IMSI_BCD_LEN 15
#define OGS_MAX_IMSI_LEN \
@ -453,6 +455,9 @@ typedef struct ogs_session_s {
uint32_t context_identifier; /* EPC */
bool default_dnn_indicator; /* 5GC */
uint8_t charging_characteristics[OGS_CHRGCHARS_LEN];
bool charging_characteristics_presence;
#define OGS_PDU_SESSION_TYPE_IPV4 1
#define OGS_PDU_SESSION_TYPE_IPV6 2
#define OGS_PDU_SESSION_TYPE_IPV4V6 3

View File

@ -57,6 +57,7 @@ struct dict_object *ogs_diam_s6a_apn_configuration = NULL;
struct dict_object *ogs_diam_s6a_max_bandwidth_ul = NULL;
struct dict_object *ogs_diam_s6a_max_bandwidth_dl = NULL;
struct dict_object *ogs_diam_s6a_pdn_type = NULL;
struct dict_object *ogs_diam_s6a_3gpp_charging_characteristics = NULL;
struct dict_object *ogs_diam_s6a_served_party_ip_address = NULL;
struct dict_object *ogs_diam_s6a_eps_subscribed_qos_profile = NULL;
struct dict_object *ogs_diam_s6a_qos_class_identifier = NULL;
@ -125,6 +126,7 @@ int ogs_diam_s6a_init(void)
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "All-APN-Configurations-Included-Indicator", &ogs_diam_s6a_all_apn_configuration_included_indicator);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "APN-Configuration", &ogs_diam_s6a_apn_configuration);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PDN-Type", &ogs_diam_s6a_pdn_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Charging-Characteristics", &ogs_diam_s6a_3gpp_charging_characteristics);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Served-Party-IP-Address", &ogs_diam_s6a_served_party_ip_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscription-Data", &ogs_diam_s6a_subscription_data);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Subscriber-Status", &ogs_diam_s6a_subscriber_status);

View File

@ -103,6 +103,7 @@ extern struct dict_object *ogs_diam_s6a_apn_configuration;
extern struct dict_object *ogs_diam_s6a_max_bandwidth_ul;
extern struct dict_object *ogs_diam_s6a_max_bandwidth_dl;
extern struct dict_object *ogs_diam_s6a_pdn_type;
extern struct dict_object *ogs_diam_s6a_3gpp_charging_characteristics;
extern struct dict_object *ogs_diam_s6a_served_party_ip_address;
extern struct dict_object *ogs_diam_s6a_eps_subscribed_qos_profile;
extern struct dict_object *ogs_diam_s6a_qos_class_identifier;

View File

@ -422,6 +422,8 @@ struct mme_ue_s {
/* HSS Info */
ogs_bitrate_t ambr; /* UE-AMBR */
uint32_t network_access_mode; /* Permitted EPS Attach Type */
uint8_t charging_characteristics[OGS_CHRGCHARS_LEN]; /* Subscription Level Charging Characteristics */
bool charging_characteristics_presence;
uint32_t context_identifier; /* default APN */

View File

@ -593,6 +593,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
{
int ret;
char buf[OGS_CHRGCHARS_LEN];
struct sess_state *sess_data = NULL;
struct timespec ts;
struct session *session;
@ -795,6 +797,26 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
ogs_warn("no subscribed Network-Access-Mode, defaulting to PACKET_AND_CIRCUIT (0)");
}
/* AVP: '3GPP-Charging-Characteristics'(13)
* For GGSN, it contains the charging characteristics for
* this PDP Context received in the Create PDP Context
* Request Message (only available in R99 and later releases).
* For PGW, it contains the charging characteristics for the
* IP-CAN bearer.
* Reference: 3GPP TS 29.061 16.4.7.2 13
*/
ret = fd_avp_search_avp(avp, ogs_diam_s6a_3gpp_charging_characteristics, &avpch1);
ogs_assert(ret == 0);
if (avpch1) {
ret = fd_msg_avp_hdr(avpch1, &hdr);
memcpy(mme_ue->charging_characteristics,
OGS_HEX(hdr->avp_value->os.data, (int)hdr->avp_value->os.len, buf), OGS_CHRGCHARS_LEN);
mme_ue->charging_characteristics_presence = true;
} else {
memcpy(mme_ue->charging_characteristics, (uint8_t *)"\x00\x00", OGS_CHRGCHARS_LEN);
mme_ue->charging_characteristics_presence = false;
}
/* AVP: 'AMBR'(1435)
* The Amber AVP contains the Max-Requested-Bandwidth-UL and
* Max-Requested-Bandwidth-DL AVPs.
@ -984,6 +1006,27 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
error++;
}
/* AVP: '3GPP-Charging-Characteristics'(13)
* For GGSN, it contains the charging characteristics for
* this PDP Context received in the Create PDP Context
* Request Message (only available in R99 and later releases).
* For PGW, it contains the charging characteristics for the
* IP-CAN bearer.
* Reference: 3GPP TS 29.061 16.4.7.2 13
*/
ret = fd_avp_search_avp(avpch2, ogs_diam_s6a_3gpp_charging_characteristics,
&avpch3);
ogs_assert(ret == 0);
if (avpch3) {
ret = fd_msg_avp_hdr(avpch3, &hdr);
memcpy(session->charging_characteristics,
OGS_HEX(hdr->avp_value->os.data, (int)hdr->avp_value->os.len, buf), OGS_CHRGCHARS_LEN);
session->charging_characteristics_presence = true;
} else {
memcpy(session->charging_characteristics, mme_ue->charging_characteristics, OGS_CHRGCHARS_LEN);
session->charging_characteristics_presence = mme_ue->charging_characteristics_presence;
}
/* AVP: 'Served-Party-IP-Address'(848)
* The Served-Party-IP-Address AVP holds the IP address of
* either the calling or called party, depending on whether

View File

@ -330,9 +330,11 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
req->ue_time_zone.data = &ue_timezone;
req->ue_time_zone.len = sizeof(ue_timezone);
req->charging_characteristics.presence = 1;
req->charging_characteristics.data = (uint8_t *)"\x54\x00";
req->charging_characteristics.len = 2;
if (session->charging_characteristics_presence == true) {
req->charging_characteristics.presence = 1;
req->charging_characteristics.data = session->charging_characteristics;
req->charging_characteristics.len = 2;
}
gtp_message.h.type = type;
return ogs_gtp2_build_msg(&gtp_message);

View File

@ -91,6 +91,11 @@ void mme_s6a_handle_ula(mme_ue_t *mme_ue,
memcpy(&mme_ue->session[i].smf_ip, &slice_data->session[i].smf_ip,
sizeof(mme_ue->session[i].smf_ip));
memcpy(&mme_ue->session[i].charging_characteristics, &slice_data->session[i].charging_characteristics,
sizeof(mme_ue->session[i].charging_characteristics));
mme_ue->session[i].charging_characteristics_presence =
slice_data->session[i].charging_characteristics_presence;
}
mme_ue->num_of_session = i;