[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:
parent
d2ef555ce4
commit
68140efce4
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(>p_message);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue