Merge branch 'main' of https://github.com/open5gs/open5gs into main

This commit is contained in:
Sukchan Lee 2022-05-11 20:40:19 +09:00
commit 53a96022d9
3 changed files with 231 additions and 72 deletions

View File

@ -46,6 +46,14 @@ struct dict_object *ogs_diam_gy_cc_service_specific_units = NULL;
struct dict_object *ogs_diam_gy_reporting_reason = NULL;
struct dict_object *ogs_diam_gy_service_id = NULL;
struct dict_object *ogs_diam_gy_service_information = NULL;
struct dict_object *ogs_diam_gy_ps_information = NULL;
struct dict_object *ogs_diam_gy_3gpp_charging_id = NULL;
struct dict_object *ogs_diam_gy_3gpp_pdp_type = NULL;
struct dict_object *ogs_diam_gy_pdp_address = NULL;
struct dict_object *ogs_diam_gy_sgsn_address = NULL;
struct dict_object *ogs_diam_gy_ggsn_address = NULL;
struct dict_object *ogs_diam_gy_feature_list_id = NULL;
struct dict_object *ogs_diam_gy_feature_list = NULL;
struct dict_object *ogs_diam_gy_qos_information = NULL;
@ -98,6 +106,14 @@ int ogs_diam_gy_init(void)
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Reporting-Reason", &ogs_diam_gy_reporting_reason);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Service-Identifier", &ogs_diam_gy_service_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Service-Information", &ogs_diam_gy_service_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PS-Information", &ogs_diam_gy_ps_information);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-Charging-Id", &ogs_diam_gy_3gpp_charging_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "3GPP-PDP-Type", &ogs_diam_gy_3gpp_pdp_type);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "PDP-Address", &ogs_diam_gy_pdp_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "SGSN-Address", &ogs_diam_gy_sgsn_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "GGSN-Address", &ogs_diam_gy_ggsn_address);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List-ID", &ogs_diam_gy_feature_list_id);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "Feature-List", &ogs_diam_gy_feature_list);
CHECK_dict_search(DICT_AVP, AVP_BY_NAME_ALL_VENDORS, "QoS-Information", &ogs_diam_gy_qos_information);

View File

@ -90,6 +90,20 @@ extern struct dict_object *ogs_diam_gy_reporting_reason;
#define OGS_DIAM_GY_REPORTING_REASON_POOL_EXHAUSTED 8
#define OGS_DIAM_GY_REPORTING_REASON_UNUSED_QUOTA_TIMER 9
extern struct dict_object *ogs_diam_gy_service_id;
extern struct dict_object *ogs_diam_gy_service_information;
extern struct dict_object *ogs_diam_gy_ps_information;
extern struct dict_object *ogs_diam_gy_3gpp_charging_id;
extern struct dict_object *ogs_diam_gy_3gpp_pdp_type;
#define OGS_DIAM_GY_3GPP_PDP_TYPE_IPv4 0
#define OGS_DIAM_GY_3GPP_PDP_TYPE_PPP 1
#define OGS_DIAM_GY_3GPP_PDP_TYPE_IPv6 2
#define OGS_DIAM_GY_3GPP_PDP_TYPE_IPv4v6 3
#define OGS_DIAM_GY_3GPP_PDP_TYPE_NON_IP 4
#define OGS_DIAM_GY_3GPP_PDP_TYPE_UNSTRUCTURED 5
#define OGS_DIAM_GY_3GPP_PDP_TYPE_ETHERNET 6
extern struct dict_object *ogs_diam_gy_pdp_address;
extern struct dict_object *ogs_diam_gy_sgsn_address;
extern struct dict_object *ogs_diam_gy_ggsn_address;
extern struct dict_object *ogs_diam_gy_feature_list_id;
extern struct dict_object *ogs_diam_gy_feature_list;
extern struct dict_object *ogs_diam_gy_qos_information;

View File

@ -244,6 +244,205 @@ static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
ogs_assert(ret == 0);
}
/* TS 32.299 7.2.192 Service-Information AVP for CCR */
static void fill_service_information_ccr(smf_sess_t *sess,
uint32_t cc_request_type, struct msg *req)
{
int ret;
union avp_value val;
struct avp *avp;
struct avp *avpch1, *avpch2;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
char buf[OGS_PLMNIDSTRLEN];
/* Service-Information, TS 32.299 sec 7.2.192 */
ret = fd_msg_avp_new(ogs_diam_gy_service_information, 0, &avp);
/* PS-Information, TS 32.299 sec 7.2.158 */
ret = fd_msg_avp_new(ogs_diam_gy_ps_information, 0, &avpch1);
/* 3GPP-Charging-Id, 3GPP TS 29.061 16.4.7.2 2 */
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_charging_id, 0, &avpch2);
ogs_assert(ret == 0);
val.u32 = sess->charging.id;
ret = fd_msg_avp_setvalue(avpch2, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
/* 3GPP-PDP-Type, 3GPP TS 29.061 16.4.7.2 3 */
if (cc_request_type == OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST) {
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_pdp_type, 0, &avpch2);
ogs_assert(ret == 0);
switch (sess->session.session_type) {
case OGS_PDU_SESSION_TYPE_IPV4:
val.i32 = OGS_DIAM_GY_3GPP_PDP_TYPE_IPv4;
break;
case OGS_PDU_SESSION_TYPE_IPV6:
val.i32 = OGS_DIAM_GY_3GPP_PDP_TYPE_IPv6;
break;
case OGS_PDU_SESSION_TYPE_IPV4V6:
val.i32 = OGS_DIAM_GY_3GPP_PDP_TYPE_IPv4v6;
break;
case OGS_PDU_SESSION_TYPE_UNSTRUCTURED:
val.i32 = OGS_DIAM_GY_3GPP_PDP_TYPE_UNSTRUCTURED;
break;
case OGS_PDU_SESSION_TYPE_ETHERNET:
val.i32 = OGS_DIAM_GY_3GPP_PDP_TYPE_ETHERNET;
break;
default:
val.i32 = OGS_DIAM_GY_3GPP_PDP_TYPE_NON_IP;
}
ret = fd_msg_avp_setvalue(avpch2, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
/* PDP-Address, TS 32.299 7.2.137 */
if (sess->ipv4) {
ret = fd_msg_avp_new(ogs_diam_gy_pdp_address, 0, &avpch2);
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr.s_addr, (uint8_t*)&sess->ipv4->addr[0], OGS_IPV4_LEN);
ret = fd_msg_avp_value_encode(&sin, avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
}
if (sess->ipv6) {
ret = fd_msg_avp_new(ogs_diam_gy_pdp_address, 0, &avpch2);
sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr.s6_addr, (uint8_t*)&sess->ipv6->addr[0], OGS_IPV6_LEN);
ret = fd_msg_avp_value_encode(&sin6, avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
/* PDP-Address-Prefix-Length, TS 32.299 7.2.137 */
/* TODO: not yet needed since used OGS_IPV6_DEFAULT_PREFIX_LEN is 64.
if (OGS_IPV6_DEFAULT_PREFIX_LEN != 64) {
.u32 = sess->ipv6->subnet->prefixlen;
}
*/
}
/* SGSN-Address */
if (sess->sgw_s5c_ip.ipv4) {
ret = fd_msg_avp_new(ogs_diam_gy_sgsn_address, 0, &avpch2);
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr.s_addr, (uint8_t*)&sess->sgw_s5c_ip.addr, OGS_IPV4_LEN);
ret = fd_msg_avp_value_encode(&sin, avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
if (sess->sgw_s5c_ip.ipv6) {
ret = fd_msg_avp_new(ogs_diam_gy_sgsn_address, 0, &avpch2);
sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr.s6_addr, (uint8_t*)&sess->sgw_s5c_ip.addr6[0], OGS_IPV6_LEN);
ret = fd_msg_avp_value_encode(&sin6, avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
/* GGSN-Address */
if (ogs_gtp_self()->gtpc_addr) {
ret = fd_msg_avp_new(ogs_diam_gy_ggsn_address, 0, &avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_value_encode(&ogs_gtp_self()->gtpc_addr->sin, avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
if (ogs_gtp_self()->gtpc_addr6) {
ret = fd_msg_avp_new(ogs_diam_gy_ggsn_address, 0, &avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_value_encode(&ogs_gtp_self()->gtpc_addr->sin6, avpch2);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
/* Called-Station-Id */
ret = fd_msg_avp_new(ogs_diam_gy_called_station_id, 0, &avpch2);
ogs_assert(ret == 0);
ogs_assert(sess->session.name);
val.os.data = (uint8_t*)sess->session.name;
val.os.len = strlen(sess->session.name);
ret = fd_msg_avp_setvalue(avpch2, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
/* 3GPP-SGSN-MCC-MNC */
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_sgsn_mcc_mnc, 0, &avpch2);
ogs_assert(ret == 0);
val.os.data = (uint8_t *)ogs_plmn_id_to_string(&sess->plmn_id, buf);
val.os.len = strlen(buf);
ret = fd_msg_avp_setvalue(avpch2, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
/* 3GPP-MS-Timezone */
if (sess->gtp.ue_timezone.presence &&
sess->gtp.ue_timezone.len && sess->gtp.ue_timezone.data) {
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_ms_timezone, 0, &avpch2);
ogs_assert(ret == 0);
val.os.data = sess->gtp.ue_timezone.data;
val.os.len = sess->gtp.ue_timezone.len;
ret = fd_msg_avp_setvalue(avpch2, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
/* 3GPP-User-Location-Info */
if (sess->gtp.user_location_information.presence) {
ogs_gtp2_uli_t uli;
int16_t uli_len;
uint8_t uli_buf[OGS_GTP2_MAX_ULI_LEN];
uli_len = ogs_gtp2_parse_uli(
&uli, &sess->gtp.user_location_information);
ogs_assert(sess->gtp.user_location_information.len == uli_len);
ogs_assert(sess->gtp.user_location_information.data);
ogs_assert(sess->gtp.user_location_information.len);
memcpy(&uli_buf, sess->gtp.user_location_information.data,
sess->gtp.user_location_information.len);
/* Update Gy ULI Type */
if (uli.flags.tai && uli.flags.e_cgi)
uli_buf[0] =
OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI;
else if (uli.flags.tai)
uli_buf[0] = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI;
else if (uli.flags.e_cgi)
uli_buf[0] = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ECGI;
if (uli_buf[0]) {
ret = fd_msg_avp_new(
ogs_diam_gy_3gpp_user_location_info, 0, &avpch2);
ogs_assert(ret == 0);
val.os.data = (uint8_t *)&uli_buf;
val.os.len = sess->gtp.user_location_information.len;
ret = fd_msg_avp_setvalue(avpch2, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
ogs_assert(ret == 0);
}
}
/* PS-Information AVP add to req: */
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
ogs_assert(ret == 0);
/* Service-Information AVP add to req: */
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
}
/* 3GPP TS 32.299 6.4.2 Credit-Control-Request message */
void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
uint32_t cc_request_type)
@ -258,7 +457,6 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
struct sess_state *sess_data = NULL, *svg;
struct session *session = NULL;
int new;
char buf[OGS_PLMNIDSTRLEN];
const char *service_context_id = "open5gs-smfd@open5gs.org";
uint32_t timestamp;
@ -550,77 +748,8 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
/* OC-Supported-Features */
/* 3GPP-User-Location-Info */
if (sess->gtp.user_location_information.presence) {
ogs_gtp2_uli_t uli;
int16_t uli_len;
uint8_t uli_buf[OGS_GTP2_MAX_ULI_LEN];
uli_len = ogs_gtp2_parse_uli(
&uli, &sess->gtp.user_location_information);
ogs_assert(sess->gtp.user_location_information.len == uli_len);
ogs_assert(sess->gtp.user_location_information.data);
ogs_assert(sess->gtp.user_location_information.len);
memcpy(&uli_buf, sess->gtp.user_location_information.data,
sess->gtp.user_location_information.len);
/* Update Gy ULI Type */
if (uli.flags.tai && uli.flags.e_cgi)
uli_buf[0] =
OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI;
else if (uli.flags.tai)
uli_buf[0] = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI;
else if (uli.flags.e_cgi)
uli_buf[0] = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ECGI;
if (uli_buf[0]) {
ret = fd_msg_avp_new(
ogs_diam_gy_3gpp_user_location_info, 0, &avp);
ogs_assert(ret == 0);
val.os.data = (uint8_t *)&uli_buf;
val.os.len = sess->gtp.user_location_information.len;
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
}
}
/* 3GPP-MS-Timezone */
if (sess->gtp.ue_timezone.presence &&
sess->gtp.ue_timezone.len && sess->gtp.ue_timezone.data) {
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_ms_timezone, 0, &avp);
ogs_assert(ret == 0);
val.os.data = sess->gtp.ue_timezone.data;
val.os.len = sess->gtp.ue_timezone.len;
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
}
/* 3GPP-SGSN-MCC-MNC */
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_sgsn_mcc_mnc, 0, &avp);
ogs_assert(ret == 0);
val.os.data = (uint8_t *)ogs_plmn_id_to_string(&sess->plmn_id, buf);
val.os.len = strlen(buf);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Called-Station-Id */
ret = fd_msg_avp_new(ogs_diam_gy_called_station_id, 0, &avp);
ogs_assert(ret == 0);
ogs_assert(sess->session.name);
val.os.data = (uint8_t*)sess->session.name;
val.os.len = strlen(sess->session.name);
ret = fd_msg_avp_setvalue(avp, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
ogs_assert(ret == 0);
/* Service-Information */
fill_service_information_ccr(sess, cc_request_type, req);
ret = clock_gettime(CLOCK_REALTIME, &sess_data->ts);