change code indentation
This commit is contained in:
parent
c530e1cbcf
commit
f28f3003c5
|
@ -1,5 +1,23 @@
|
|||
#include "ogs-crypt.h"
|
||||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ogs-crypt.h"
|
||||
#include "fd/fd-lib.h"
|
||||
#include "fd/s6a/s6a-dict.h"
|
||||
#include "fd/s6a/s6a-message.h"
|
||||
|
@ -74,15 +92,13 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_min(hdr->avp_value->os.len, MAX_IMSI_BCD_LEN)+1);
|
||||
|
||||
rv = hss_db_auth_info(imsi_bcd, &auth_info);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
result_code = S6A_DIAMETER_ERROR_USER_UNKNOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(zero, 0, sizeof(zero));
|
||||
if (memcmp(auth_info.rand, zero, RAND_LEN) == 0)
|
||||
{
|
||||
if (memcmp(auth_info.rand, zero, RAND_LEN) == 0) {
|
||||
ogs_random(auth_info.rand, RAND_LEN);
|
||||
}
|
||||
|
||||
|
@ -93,25 +109,20 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
ret = fd_msg_search_avp(qry, s6a_req_eutran_auth_info, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, s6a_re_synchronization_info, &avpch);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch)
|
||||
{
|
||||
if (avpch) {
|
||||
ret = fd_msg_avp_hdr(avpch, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
hss_auc_sqn(opc, auth_info.k, hdr->avp_value->os.data, sqn, mac_s);
|
||||
if (memcmp(mac_s, hdr->avp_value->os.data +
|
||||
RAND_LEN + HSS_SQN_LEN, MAC_S_LEN) == 0)
|
||||
{
|
||||
RAND_LEN + HSS_SQN_LEN, MAC_S_LEN) == 0) {
|
||||
ogs_random(auth_info.rand, RAND_LEN);
|
||||
auth_info.sqn = ogs_buffer_to_uint64(sqn, HSS_SQN_LEN);
|
||||
/* 33.102 C.3.4 Guide : IND + 1 */
|
||||
auth_info.sqn = (auth_info.sqn + 32 + 1) & HSS_MAX_SQN;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("Re-synch MAC failed for IMSI:`%s`", imsi_bcd);
|
||||
ogs_log_print(OGS_LOG_ERROR, "MAC_S: ");
|
||||
ogs_log_hexdump(OGS_LOG_ERROR, mac_s, MAC_S_LEN);
|
||||
|
@ -127,16 +138,14 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
|
|||
}
|
||||
|
||||
rv = hss_db_update_rand_and_sqn(imsi_bcd, auth_info.rand, auth_info.sqn);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("Cannot update rand and sqn for IMSI:'%s'", imsi_bcd);
|
||||
result_code = S6A_DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = hss_db_increment_sqn(imsi_bcd);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("Cannot increment sqn for IMSI:'%s'", imsi_bcd);
|
||||
result_code = S6A_DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE;
|
||||
goto out;
|
||||
|
@ -291,8 +300,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_min(hdr->avp_value->os.len, MAX_IMSI_BCD_LEN)+1);
|
||||
|
||||
rv = hss_db_subscription_data(imsi_bcd, &subscription_data);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("Cannot get Subscription-Data for IMSI:'%s'", imsi_bcd);
|
||||
result_code = S6A_DIAMETER_ERROR_USER_UNKNOWN;
|
||||
goto out;
|
||||
|
@ -332,8 +340,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (!(hdr->avp_value->u32 & S6A_ULR_SKIP_SUBSCRIBER_DATA))
|
||||
{
|
||||
if (!(hdr->avp_value->u32 & S6A_ULR_SKIP_SUBSCRIBER_DATA)) {
|
||||
struct avp *avp_access_restriction_data;
|
||||
struct avp *avp_subscriber_status, *avp_network_access_mode;
|
||||
struct avp *avp_ambr, *avp_max_bandwidth_ul, *avp_max_bandwidth_dl;
|
||||
|
@ -343,8 +350,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ret = fd_msg_avp_new(s6a_subscription_data, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (subscription_data.access_restriction_data)
|
||||
{
|
||||
if (subscription_data.access_restriction_data) {
|
||||
ret = fd_msg_avp_new(s6a_access_restriction_data, 0,
|
||||
&avp_access_restriction_data);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -393,8 +399,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avp_ambr);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (subscription_data.num_of_pdn)
|
||||
{
|
||||
if (subscription_data.num_of_pdn) {
|
||||
/* Set the APN Configuration Profile */
|
||||
struct avp *apn_configuration_profile;
|
||||
struct avp *context_identifier;
|
||||
|
@ -427,8 +432,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
all_apn_configuration_included_indicator);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
for (i = 0; i < subscription_data.num_of_pdn; i++)
|
||||
{
|
||||
for (i = 0; i < subscription_data.num_of_pdn; i++) {
|
||||
/* Set the APN Configuration */
|
||||
struct avp *apn_configuration, *context_identifier;
|
||||
struct avp *pdn_type, *service_selection;
|
||||
|
@ -536,14 +540,12 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(ret == 0);
|
||||
|
||||
/* Set MIP6-Agent-Info */
|
||||
if (pdn->pgw_ip.ipv4 || pdn->pgw_ip.ipv6)
|
||||
{
|
||||
if (pdn->pgw_ip.ipv4 || pdn->pgw_ip.ipv6) {
|
||||
ret = fd_msg_avp_new(fd_mip6_agent_info, 0,
|
||||
&mip6_agent_info);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (pdn->pgw_ip.ipv4)
|
||||
{
|
||||
if (pdn->pgw_ip.ipv4) {
|
||||
ret = fd_msg_avp_new(fd_mip_home_agent_address, 0,
|
||||
&mip_home_agent_address);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -557,8 +559,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (pdn->pgw_ip.ipv6)
|
||||
{
|
||||
if (pdn->pgw_ip.ipv6) {
|
||||
ret = fd_msg_avp_new(fd_mip_home_agent_address, 0,
|
||||
&mip_home_agent_address);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -579,8 +580,7 @@ static int hss_s6a_ulr_cb( struct msg **msg, struct avp *avp,
|
|||
}
|
||||
|
||||
/* Set AMBR */
|
||||
if (pdn->ambr.downlink || pdn->ambr.uplink)
|
||||
{
|
||||
if (pdn->ambr.downlink || pdn->ambr.uplink) {
|
||||
ret = fd_msg_avp_new(s6a_ambr, 0, &avp_ambr);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_new(s6a_max_bandwidth_ul, 0,
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fd/fd-lib.h"
|
||||
#include "fd/s6a/s6a-dict.h"
|
||||
#include "fd/s6a/s6a-message.h"
|
||||
|
@ -113,8 +132,7 @@ void mme_s6a_send_air(mme_ue_t *mme_ue,
|
|||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (authentication_failure_parameter)
|
||||
{
|
||||
if (authentication_failure_parameter) {
|
||||
ret = fd_msg_avp_new(s6a_re_synchronization_info, 0, &avpch);
|
||||
ogs_assert(ret == 0);
|
||||
memcpy(resync, mme_ue->rand, RAND_LEN);
|
||||
|
@ -225,32 +243,25 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
|
|||
/* Value of Result Code */
|
||||
ret = fd_msg_search_avp(*msg, fd_result_code, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
s6a_message->result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Result Code: %d", hdr->avp_value->i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_msg_search_avp(*msg, fd_experimental_result, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, fd_experimental_result_code, &avpch);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch)
|
||||
{
|
||||
if (avpch) {
|
||||
ret = fd_msg_avp_hdr(avpch, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
s6a_message->result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Experimental Result Code: %d",
|
||||
s6a_message->result_code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no Result-Code");
|
||||
error++;
|
||||
}
|
||||
|
@ -259,15 +270,12 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Host */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_host, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" From '%.*s'",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Host ");
|
||||
error++;
|
||||
}
|
||||
|
@ -275,114 +283,91 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Realm */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_realm, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" ('%.*s')",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Realm ");
|
||||
error++;
|
||||
}
|
||||
|
||||
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
|
||||
{
|
||||
if (s6a_message->result_code != ER_DIAMETER_SUCCESS) {
|
||||
ogs_warn("ERROR DIAMETER Result Code(%d)", s6a_message->result_code);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, s6a_authentication_info, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Authentication-Info ");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avp, s6a_e_utran_vector, &avp_e_utran_vector);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp_e_utran_vector, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_E-UTRAN-Vector-Info ");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avp_e_utran_vector, s6a_xres, &avp_xres);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp_xres, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
memcpy(e_utran_vector->xres,
|
||||
hdr->avp_value->os.data, hdr->avp_value->os.len);
|
||||
e_utran_vector->xres_len = hdr->avp_value->os.len;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_XRES");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avp_e_utran_vector, s6a_kasme, &avp_kasme);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp_kasme, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
memcpy(e_utran_vector->kasme,
|
||||
hdr->avp_value->os.data, hdr->avp_value->os.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_KASME");
|
||||
error++;
|
||||
}
|
||||
|
||||
|
||||
ret = fd_avp_search_avp(avp_e_utran_vector, s6a_rand, &avp_rand);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp_rand, &hdr);
|
||||
memcpy(e_utran_vector->rand,
|
||||
hdr->avp_value->os.data, hdr->avp_value->os.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_RAND");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avp_e_utran_vector, s6a_autn, &avp_autn);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp_autn, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
memcpy(e_utran_vector->autn,
|
||||
hdr->avp_value->os.data, hdr->avp_value->os.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_AUTN");
|
||||
error++;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!error)
|
||||
{
|
||||
if (!error) {
|
||||
int rv;
|
||||
e = mme_event_new(MME_EVT_S6A_MESSAGE);
|
||||
ogs_assert(e);
|
||||
|
@ -402,8 +387,7 @@ out:
|
|||
ogs_assert(pthread_mutex_lock(&fd_logger_self()->stats_lock) == 0);
|
||||
dur = ((ts.tv_sec - sess_data->ts.tv_sec) * 1000000) +
|
||||
((ts.tv_nsec - sess_data->ts.tv_nsec) / 1000);
|
||||
if (fd_logger_self()->stats.nb_recv)
|
||||
{
|
||||
if (fd_logger_self()->stats.nb_recv) {
|
||||
/* Ponderate in the avg */
|
||||
fd_logger_self()->stats.avg = (fd_logger_self()->stats.avg *
|
||||
fd_logger_self()->stats.nb_recv + dur) /
|
||||
|
@ -413,9 +397,7 @@ out:
|
|||
fd_logger_self()->stats.shortest = dur;
|
||||
if (dur > fd_logger_self()->stats.longest)
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fd_logger_self()->stats.shortest = dur;
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
fd_logger_self()->stats.avg = dur;
|
||||
|
@ -631,32 +613,25 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
/* Value of Result Code */
|
||||
ret = fd_msg_search_avp(*msg, fd_result_code, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
s6a_message->result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Result Code: %d", hdr->avp_value->i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_msg_search_avp(*msg, fd_experimental_result, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, fd_experimental_result_code, &avpch);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch)
|
||||
{
|
||||
if (avpch) {
|
||||
ret = fd_msg_avp_hdr(avpch, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
s6a_message->result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Experimental Result Code: %d",
|
||||
s6a_message->result_code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no Result-Code");
|
||||
error++;
|
||||
}
|
||||
|
@ -665,15 +640,12 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Host */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_host, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" From '%.*s'",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Host");
|
||||
error++;
|
||||
}
|
||||
|
@ -681,29 +653,23 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Realm */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_realm, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" ('%.*s')",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Realm");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, s6a_ula_flags, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ula_message->ula_flags = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_ULA-Flags");
|
||||
error++;
|
||||
}
|
||||
|
@ -711,331 +677,267 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
|
||||
ret = fd_msg_search_avp(*msg, s6a_subscription_data, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, s6a_ambr, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_avp_search_avp( avpch1, s6a_max_bandwidth_ul, &avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch2)
|
||||
{
|
||||
if (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
subscription_data->ambr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Max-Bandwidth-UL");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch1, s6a_max_bandwidth_dl, &avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch2)
|
||||
{
|
||||
if (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
subscription_data->ambr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Max-Bandwidth-DL");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_AMBR");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avp, s6a_apn_configuration_profile, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch2)
|
||||
{
|
||||
while (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
switch(hdr->avp_code) {
|
||||
case S6A_AVP_CODE_CONTEXT_IDENTIFIER:
|
||||
subscription_data->context_identifier =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case S6A_AVP_CODE_ALL_APN_CONFIG_INC_IND:
|
||||
break;
|
||||
case S6A_AVP_CODE_APN_CONFIGURATION:
|
||||
{
|
||||
case S6A_AVP_CODE_CONTEXT_IDENTIFIER:
|
||||
{
|
||||
subscription_data->context_identifier =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
pdn_t *pdn = &subscription_data->pdn[
|
||||
subscription_data->num_of_pdn];
|
||||
ogs_assert(pdn);
|
||||
ret = fd_avp_search_avp(
|
||||
avpch2, s6a_service_selection, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_cpystrn(pdn->apn,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
ogs_min(hdr->avp_value->os.len, MAX_APN_LEN)+1);
|
||||
} else {
|
||||
ogs_error("no_Service-Selection");
|
||||
error++;
|
||||
}
|
||||
case S6A_AVP_CODE_ALL_APN_CONFIG_INC_IND:
|
||||
break;
|
||||
case S6A_AVP_CODE_APN_CONFIGURATION:
|
||||
{
|
||||
pdn_t *pdn = &subscription_data->pdn[
|
||||
subscription_data->num_of_pdn];
|
||||
ogs_assert(pdn);
|
||||
ret = fd_avp_search_avp(
|
||||
avpch2, s6a_service_selection, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_cpystrn(pdn->apn,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
ogs_min(hdr->avp_value->os.len, MAX_APN_LEN)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Service-Selection");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
s6a_context_identifier, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
pdn->context_identifier = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Context-Identifier");
|
||||
error++;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
s6a_context_identifier, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
pdn->context_identifier = hdr->avp_value->i32;
|
||||
} else {
|
||||
ogs_error("no_Context-Identifier");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, s6a_pdn_type, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
pdn->pdn_type = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_PDN-Type");
|
||||
error++;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2, s6a_pdn_type, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
pdn->pdn_type = hdr->avp_value->i32;
|
||||
} else {
|
||||
ogs_error("no_PDN-Type");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
s6a_eps_subscribed_qos_profile, &avpch3);
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
s6a_eps_subscribed_qos_profile, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_qos_class_identifier, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_qos_class_identifier, &avpch4);
|
||||
if (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
pdn->qos.qci = hdr->avp_value->i32;
|
||||
} else {
|
||||
ogs_error("no_QoS-Class-Identifier");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_allocation_retention_priority, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4) {
|
||||
ret = fd_avp_search_avp(avpch4,
|
||||
s6a_priority_level, &avpch5);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch5) {
|
||||
ret = fd_msg_avp_hdr(avpch5, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->qos.qci = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_QoS-Class-Identifier");
|
||||
pdn->qos.arp.priority_level =
|
||||
hdr->avp_value->i32;
|
||||
|
||||
} else {
|
||||
ogs_error("no_ARP");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_allocation_retention_priority, &avpch4);
|
||||
ret = fd_avp_search_avp(avpch4,
|
||||
s6a_pre_emption_capability, &avpch5);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch4,
|
||||
s6a_priority_level, &avpch5);
|
||||
if (avpch5) {
|
||||
ret = fd_msg_avp_hdr(avpch5, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch5)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch5, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->qos.arp.priority_level =
|
||||
hdr->avp_value->i32;
|
||||
pdn->qos.arp.pre_emption_capability =
|
||||
hdr->avp_value->i32;
|
||||
} else {
|
||||
ogs_error("no_Preemption-Capability");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch4,
|
||||
s6a_pre_emption_vulnerability, &avpch5);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch5) {
|
||||
ret = fd_msg_avp_hdr(avpch5, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->qos.arp.pre_emption_vulnerability =
|
||||
hdr->avp_value->i32;
|
||||
} else {
|
||||
ogs_error("no_Preemption-Vulnerability");
|
||||
error++;
|
||||
}
|
||||
|
||||
} else {
|
||||
ogs_error("no_QCI");
|
||||
error++;
|
||||
}
|
||||
} else {
|
||||
ogs_error("no_EPS-Subscribed-QoS-Profile");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
fd_mip6_agent_info, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_browse(avpch3,
|
||||
MSG_BRW_FIRST_CHILD, &avpch4, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
switch(hdr->avp_code) {
|
||||
case S6A_AVP_CODE_MIP_HOME_AGENT_ADDRESS:
|
||||
{
|
||||
ogs_sockaddr_t addr;
|
||||
|
||||
ret = fd_msg_avp_value_interpret(avpch4,
|
||||
&addr.sa);
|
||||
ogs_assert(ret == 0);
|
||||
if (addr.ogs_sa_family == AF_INET)
|
||||
{
|
||||
pdn->pgw_ip.ipv4 = 1;
|
||||
pdn->pgw_ip.both.addr =
|
||||
addr.sin.sin_addr.s_addr;
|
||||
}
|
||||
else if (addr.ogs_sa_family == AF_INET6)
|
||||
{
|
||||
pdn->pgw_ip.ipv6 = 1;
|
||||
memcpy(pdn->pgw_ip.both.addr6,
|
||||
addr.sin6.sin6_addr.s6_addr,
|
||||
IPV6_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_ARP");
|
||||
ogs_error("Invald family:%d",
|
||||
addr.ogs_sa_family);
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch4,
|
||||
s6a_pre_emption_capability, &avpch5);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch5)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch5, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->qos.arp.pre_emption_capability =
|
||||
hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Preemption-Capability");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch4,
|
||||
s6a_pre_emption_vulnerability, &avpch5);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch5)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch5, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->qos.arp.pre_emption_vulnerability =
|
||||
hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Preemption-Vulnerability");
|
||||
error++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_QCI");
|
||||
default:
|
||||
ogs_error("Unknown AVP-Code:%d",
|
||||
hdr->avp_code);
|
||||
error++;
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch4, MSG_BRW_NEXT,
|
||||
&avpch4, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_EPS-Subscribed-QoS-Profile");
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, s6a_ambr, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_max_bandwidth_ul, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->ambr.uplink = hdr->avp_value->u32;
|
||||
} else {
|
||||
ogs_error("no_Max-Bandwidth-UL");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
fd_mip6_agent_info, &avpch3);
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_max_bandwidth_dl, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_browse(avpch3,
|
||||
MSG_BRW_FIRST_CHILD, &avpch4, NULL);
|
||||
if (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case S6A_AVP_CODE_MIP_HOME_AGENT_ADDRESS:
|
||||
{
|
||||
ogs_sockaddr_t addr;
|
||||
|
||||
ret = fd_msg_avp_value_interpret(avpch4,
|
||||
&addr.sa);
|
||||
ogs_assert(ret == 0);
|
||||
if (addr.ogs_sa_family == AF_INET)
|
||||
{
|
||||
pdn->pgw_ip.ipv4 = 1;
|
||||
pdn->pgw_ip.both.addr =
|
||||
addr.sin.sin_addr.s_addr;
|
||||
}
|
||||
else if (addr.ogs_sa_family == AF_INET6)
|
||||
{
|
||||
pdn->pgw_ip.ipv6 = 1;
|
||||
memcpy(pdn->pgw_ip.both.addr6,
|
||||
addr.sin6.sin6_addr.s6_addr,
|
||||
IPV6_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("Invald family:%d",
|
||||
addr.ogs_sa_family);
|
||||
error++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Unknown AVP-Code:%d",
|
||||
hdr->avp_code);
|
||||
error++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch4, MSG_BRW_NEXT,
|
||||
&avpch4, NULL);
|
||||
}
|
||||
pdn->ambr.downlink = hdr->avp_value->u32;
|
||||
} else {
|
||||
ogs_error("no_Max-Bandwidth-DL");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, s6a_ambr, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_max_bandwidth_ul, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->ambr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Max-Bandwidth-UL");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
s6a_max_bandwidth_dl, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pdn->ambr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Max-Bandwidth-DL");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
|
||||
subscription_data->num_of_pdn++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_warn("Unknown AVP-code:%d", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
|
||||
subscription_data->num_of_pdn++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ogs_warn("Unknown AVP-code:%d", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
|
||||
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_APN-Configuration-Profile");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Subscription-Data");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, s6a_subscribed_rau_tau_timer, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
subscription_data->subscribed_rau_tau_timer = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Subscribed_RAU-TAU-Timer");
|
||||
error++;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
{
|
||||
if (!error) {
|
||||
int rv;
|
||||
e = mme_event_new(MME_EVT_S6A_MESSAGE);
|
||||
ogs_assert(e);
|
||||
|
@ -1055,8 +957,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
ogs_assert(pthread_mutex_lock(&fd_logger_self()->stats_lock) == 0);
|
||||
dur = ((ts.tv_sec - sess_data->ts.tv_sec) * 1000000) +
|
||||
((ts.tv_nsec - sess_data->ts.tv_nsec) / 1000);
|
||||
if (fd_logger_self()->stats.nb_recv)
|
||||
{
|
||||
if (fd_logger_self()->stats.nb_recv) {
|
||||
/* Ponderate in the avg */
|
||||
fd_logger_self()->stats.avg = (fd_logger_self()->stats.avg *
|
||||
fd_logger_self()->stats.nb_recv + dur) /
|
||||
|
@ -1066,9 +967,7 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
fd_logger_self()->stats.shortest = dur;
|
||||
if (dur > fd_logger_self()->stats.longest)
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fd_logger_self()->stats.shortest = dur;
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
fd_logger_self()->stats.avg = dur;
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#include "fd/fd-lib.h"
|
||||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fd/fd-lib.h"
|
||||
#include "pcrf-context.h"
|
||||
#include "pcrf-fd-path.h"
|
||||
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fd/fd-lib.h"
|
||||
#include "fd/gx/gx-dict.h"
|
||||
#include "fd/rx/rx-dict.h"
|
||||
|
@ -94,8 +113,7 @@ static int remove_rx_state(struct rx_sess_state *rx_sess_data)
|
|||
ogs_assert(rx_sess_data);
|
||||
gx = rx_sess_data->gx;
|
||||
|
||||
for (i = 0; i < rx_sess_data->num_of_pcc_rule; i++)
|
||||
{
|
||||
for (i = 0; i < rx_sess_data->num_of_pcc_rule; i++) {
|
||||
PCC_RULE_FREE(&rx_sess_data->pcc_rule[i]);
|
||||
}
|
||||
|
||||
|
@ -127,8 +145,7 @@ static struct rx_sess_state *find_rx_state(struct sess_state *gx, os0_t sid)
|
|||
ogs_assert(gx);
|
||||
ogs_assert(sid);
|
||||
|
||||
ogs_list_for_each(&gx->rx_list, rx_sess_data)
|
||||
{
|
||||
ogs_list_for_each(&gx->rx_list, rx_sess_data) {
|
||||
if (!strcmp((char *)rx_sess_data->sid, (char *)sid))
|
||||
return rx_sess_data;
|
||||
}
|
||||
|
@ -194,8 +211,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
ret = fd_sess_state_retrieve(pcrf_gx_reg, sess, &sess_data);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (!sess_data)
|
||||
{
|
||||
if (!sess_data) {
|
||||
os0_t sid;
|
||||
size_t sidlen;
|
||||
|
||||
|
@ -218,8 +234,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get Origin-Host */
|
||||
ret = fd_msg_search_avp(qry, fd_origin_host, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
|
@ -228,9 +243,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
sess_data->peer_host =
|
||||
(os0_t)ogs_strdup((char *)hdr->avp_value->os.data);
|
||||
ogs_assert(sess_data->peer_host);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_CC-Request-Type ");
|
||||
result_code = FD_DIAMETER_MISSING_AVP;
|
||||
goto out;
|
||||
|
@ -239,14 +252,11 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get CC-Request-Type */
|
||||
ret = fd_msg_search_avp(qry, gx_cc_request_type, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
sess_data->cc_request_type = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_CC-Request-Type ");
|
||||
result_code = FD_DIAMETER_MISSING_AVP;
|
||||
goto out;
|
||||
|
@ -255,8 +265,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get CC-Request-Number */
|
||||
ret = fd_msg_search_avp(qry, gx_cc_request_number, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
cc_request_number = hdr->avp_value->i32;
|
||||
|
@ -265,8 +274,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get Framed-IP-Address */
|
||||
ret = fd_msg_search_avp(qry, gx_framed_ip_address, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
|
@ -279,8 +287,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get Framed-IPv6-Prefix */
|
||||
ret = fd_msg_search_avp(qry, gx_framed_ipv6_prefix, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
paa_t *paa = NULL;
|
||||
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
|
@ -324,51 +331,42 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get IMSI + APN */
|
||||
ret = fd_msg_search_avp(qry, gx_subscription_id, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_avp_search_avp(avp, gx_subscription_id_type, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (hdr->avp_value->i32 != GX_SUBSCRIPTION_ID_TYPE_END_USER_IMSI)
|
||||
{
|
||||
if (hdr->avp_value->i32 != GX_SUBSCRIPTION_ID_TYPE_END_USER_IMSI) {
|
||||
ogs_error("Not implemented Subscription-Id-Type(%d)",
|
||||
hdr->avp_value->i32);
|
||||
result_code = FD_DIAMETER_AVP_UNSUPPORTED;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Subscription-Id-Type");
|
||||
result_code = FD_DIAMETER_MISSING_AVP;
|
||||
goto out;
|
||||
}
|
||||
ret = fd_avp_search_avp(avp, gx_subscription_id_data, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (sess_data->imsi_bcd)
|
||||
ogs_free(sess_data->imsi_bcd);
|
||||
sess_data->imsi_bcd = ogs_strdup((char *)hdr->avp_value->os.data);
|
||||
ogs_assert(sess_data->imsi_bcd);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Subscription-Id-Data");
|
||||
result_code = FD_DIAMETER_MISSING_AVP;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (sess_data->imsi_bcd == NULL)
|
||||
{
|
||||
if (sess_data->imsi_bcd == NULL) {
|
||||
ogs_error("no_Subscription-Id");
|
||||
result_code = FD_DIAMETER_MISSING_AVP;
|
||||
goto out;
|
||||
|
@ -376,8 +374,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
ret = fd_msg_search_avp(qry, gx_called_station_id, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (sess_data->apn)
|
||||
|
@ -386,8 +383,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(sess_data->apn);
|
||||
}
|
||||
|
||||
if (sess_data->apn == NULL)
|
||||
{
|
||||
if (sess_data->apn == NULL) {
|
||||
ogs_error("no_Called-Station-Id");
|
||||
result_code = FD_DIAMETER_MISSING_AVP;
|
||||
goto out;
|
||||
|
@ -395,8 +391,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
/* Retrieve QoS Data from Database */
|
||||
rv = pcrf_db_qos_data(sess_data->imsi_bcd, sess_data->apn, &gx_message);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("Cannot get data for IMSI(%s)+APN(%s)'",
|
||||
sess_data->imsi_bcd, sess_data->apn);
|
||||
result_code = FD_DIAMETER_UNKNOWN_SESSION_ID;
|
||||
|
@ -404,17 +399,13 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
}
|
||||
|
||||
if (sess_data->cc_request_type == GX_CC_REQUEST_TYPE_INITIAL_REQUEST ||
|
||||
sess_data->cc_request_type == GX_CC_REQUEST_TYPE_UPDATE_REQUEST)
|
||||
{
|
||||
sess_data->cc_request_type == GX_CC_REQUEST_TYPE_UPDATE_REQUEST) {
|
||||
int charging_rule = 0;
|
||||
|
||||
for (i = 0; i < gx_message.num_of_pcc_rule; i++)
|
||||
{
|
||||
for (i = 0; i < gx_message.num_of_pcc_rule; i++) {
|
||||
pcc_rule_t *pcc_rule = &gx_message.pcc_rule[i];
|
||||
if (pcc_rule->num_of_flow)
|
||||
{
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
if (pcc_rule->num_of_flow) {
|
||||
if (charging_rule == 0) {
|
||||
ret = fd_msg_avp_new(gx_charging_rule_install, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
|
@ -426,20 +417,17 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
}
|
||||
}
|
||||
|
||||
if (charging_rule)
|
||||
{
|
||||
if (charging_rule) {
|
||||
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
/* Set QoS-Information */
|
||||
if (gx_message.pdn.ambr.downlink || gx_message.pdn.ambr.uplink)
|
||||
{
|
||||
if (gx_message.pdn.ambr.downlink || gx_message.pdn.ambr.uplink) {
|
||||
ret = fd_msg_avp_new(gx_qos_information, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (gx_message.pdn.ambr.uplink)
|
||||
{
|
||||
if (gx_message.pdn.ambr.uplink) {
|
||||
ret = fd_msg_avp_new(gx_apn_aggregate_max_bitrate_ul, 0,
|
||||
&avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -450,8 +438,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (gx_message.pdn.ambr.downlink)
|
||||
{
|
||||
if (gx_message.pdn.ambr.downlink) {
|
||||
ret = fd_msg_avp_new(gx_apn_aggregate_max_bitrate_dl, 0,
|
||||
&avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -533,14 +520,11 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
ret = fd_msg_avp_add(ans, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (sess_data->cc_request_type ==
|
||||
GX_CC_REQUEST_TYPE_TERMINATION_REQUEST)
|
||||
{
|
||||
} else if (sess_data->cc_request_type ==
|
||||
GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
|
||||
struct rx_sess_state *rx_sess_data = NULL, *next_rx_sess_data = NULL;
|
||||
ogs_list_for_each_safe(&sess_data->rx_list,
|
||||
next_rx_sess_data, rx_sess_data)
|
||||
{
|
||||
next_rx_sess_data, rx_sess_data) {
|
||||
rv = pcrf_rx_send_asr(
|
||||
rx_sess_data->sid, RX_ABORT_CAUSE_BEARER_RELEASED);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
@ -553,15 +537,12 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
ret = fd_msg_rescode_set(ans, "DIAMETER_SUCCESS", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST)
|
||||
{
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
|
||||
/* Store this value in the session */
|
||||
ret = fd_sess_state_store(pcrf_gx_reg, sess, &sess_data);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_assert(sess_data == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
state_cleanup(sess_data, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -582,38 +563,28 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
out:
|
||||
/* Set the Result-Code */
|
||||
if (result_code == FD_DIAMETER_AVP_UNSUPPORTED)
|
||||
{
|
||||
if (result_code == FD_DIAMETER_AVP_UNSUPPORTED) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_AVP_UNSUPPORTED", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID)
|
||||
{
|
||||
} else if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_UNKNOWN_SESSION_ID", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (result_code == FD_DIAMETER_MISSING_AVP)
|
||||
{
|
||||
} else if (result_code == FD_DIAMETER_MISSING_AVP) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_MISSING_AVP", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_message_experimental_rescode_set(ans, result_code);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST)
|
||||
{
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
|
||||
/* Store this value in the session */
|
||||
ret = fd_sess_state_store(pcrf_gx_reg, sess, &sess_data);
|
||||
ogs_assert(sess_data == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
state_cleanup(sess_data, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -670,8 +641,7 @@ int pcrf_gx_send_rar(
|
|||
sidlen = strlen((char *)gx_sid);
|
||||
ret = fd_sess_fromsid_msg((os0_t)gx_sid, sidlen, &session, &new);
|
||||
ogs_assert(ret == 0);
|
||||
if (new)
|
||||
{
|
||||
if (new) {
|
||||
ogs_error("No session data");
|
||||
ret = fd_msg_free(req);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -690,8 +660,7 @@ int pcrf_gx_send_rar(
|
|||
/* Retrieve session state in this session */
|
||||
ret = fd_sess_state_retrieve(pcrf_gx_reg, session, &sess_data);
|
||||
ogs_assert(ret == 0);
|
||||
if (sess_data == NULL)
|
||||
{
|
||||
if (sess_data == NULL) {
|
||||
ogs_error("No session data");
|
||||
ret = fd_msg_free(req);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -701,18 +670,15 @@ int pcrf_gx_send_rar(
|
|||
|
||||
/* Find RX session state */
|
||||
rx_sess_data = find_rx_state(sess_data, rx_sid);
|
||||
if (rx_message->cmd_code == RX_CMD_CODE_AA)
|
||||
{
|
||||
if (!rx_sess_data)
|
||||
{
|
||||
if (rx_message->cmd_code == RX_CMD_CODE_AA) {
|
||||
if (!rx_sess_data) {
|
||||
rx_sess_data = add_rx_state(sess_data, rx_sid);
|
||||
ogs_assert(rx_sess_data);
|
||||
}
|
||||
|
||||
/* Retrieve QoS Data from Database */
|
||||
rv = pcrf_db_qos_data(sess_data->imsi_bcd, sess_data->apn, &gx_message);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("Cannot get data for IMSI(%s)+APN(%s)'",
|
||||
sess_data->imsi_bcd, sess_data->apn);
|
||||
rx_message->result_code =
|
||||
|
@ -721,8 +687,7 @@ int pcrf_gx_send_rar(
|
|||
}
|
||||
|
||||
/* Match Media-Component with PCC Rule */
|
||||
for (i = 0; i < rx_message->num_of_media_component; i++)
|
||||
{
|
||||
for (i = 0; i < rx_message->num_of_media_component; i++) {
|
||||
int flow_presence = 0;
|
||||
pcc_rule_t *pcc_rule = NULL;
|
||||
pcc_rule_t *db_pcc_rule = NULL;
|
||||
|
@ -730,38 +695,29 @@ int pcrf_gx_send_rar(
|
|||
rx_media_component_t *media_component =
|
||||
&rx_message->media_component[i];
|
||||
|
||||
if (media_component->media_component_number == 0)
|
||||
{
|
||||
if (media_component->media_component_number == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(media_component->media_type)
|
||||
{
|
||||
case RX_MEDIA_TYPE_AUDIO:
|
||||
{
|
||||
qci = PDN_QCI_1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not implemented : [Media-Type:%d]",
|
||||
media_component->media_type);
|
||||
rx_message->result_code = FD_DIAMETER_INVALID_AVP_VALUE;
|
||||
goto out;
|
||||
}
|
||||
switch(media_component->media_type) {
|
||||
case RX_MEDIA_TYPE_AUDIO:
|
||||
qci = PDN_QCI_1;
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not implemented : [Media-Type:%d]",
|
||||
media_component->media_type);
|
||||
rx_message->result_code = FD_DIAMETER_INVALID_AVP_VALUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (j = 0; j < gx_message.num_of_pcc_rule; j++)
|
||||
{
|
||||
if (gx_message.pcc_rule[j].qos.qci == qci)
|
||||
{
|
||||
for (j = 0; j < gx_message.num_of_pcc_rule; j++) {
|
||||
if (gx_message.pcc_rule[j].qos.qci == qci) {
|
||||
db_pcc_rule = &gx_message.pcc_rule[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!db_pcc_rule)
|
||||
{
|
||||
if (!db_pcc_rule) {
|
||||
ogs_error("CHECK WEBUI : No PCC Rule in DB [QCI:%d]", qci);
|
||||
ogs_error("Please add PCC Rule using WEBUI");
|
||||
rx_message->result_code =
|
||||
|
@ -769,17 +725,14 @@ int pcrf_gx_send_rar(
|
|||
goto out;
|
||||
}
|
||||
|
||||
for (j = 0; j < rx_sess_data->num_of_pcc_rule; j++)
|
||||
{
|
||||
if (rx_sess_data->pcc_rule[j].qos.qci == qci)
|
||||
{
|
||||
for (j = 0; j < rx_sess_data->num_of_pcc_rule; j++) {
|
||||
if (rx_sess_data->pcc_rule[j].qos.qci == qci) {
|
||||
pcc_rule = &rx_sess_data->pcc_rule[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pcc_rule)
|
||||
{
|
||||
if (!pcc_rule) {
|
||||
pcc_rule =
|
||||
&rx_sess_data->pcc_rule[rx_sess_data->num_of_pcc_rule];
|
||||
|
||||
|
@ -795,35 +748,29 @@ int pcrf_gx_send_rar(
|
|||
/* Install Flow */
|
||||
flow_presence = 1;
|
||||
rv = install_flow(pcc_rule, media_component);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
rx_message->result_code = RX_DIAMETER_FILTER_RESTRICTIONS;
|
||||
ogs_error("install_flow() failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rx_sess_data->num_of_pcc_rule++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_assert(strcmp(pcc_rule->name, db_pcc_rule->name) == 0);
|
||||
|
||||
/* Check Flow */
|
||||
count = matched_flow(pcc_rule, media_component);
|
||||
if (count == -1)
|
||||
{
|
||||
if (count == -1) {
|
||||
rx_message->result_code = RX_DIAMETER_FILTER_RESTRICTIONS;
|
||||
ogs_error("matched_flow() failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pcc_rule->num_of_flow != count)
|
||||
{
|
||||
if (pcc_rule->num_of_flow != count) {
|
||||
/* Re-install Flow */
|
||||
flow_presence = 1;
|
||||
rv = install_flow(pcc_rule, media_component);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
rx_message->result_code =
|
||||
RX_DIAMETER_FILTER_RESTRICTIONS;
|
||||
ogs_error("install_flow() failed");
|
||||
|
@ -836,8 +783,7 @@ int pcrf_gx_send_rar(
|
|||
|
||||
/* Update QoS */
|
||||
rv = update_qos(pcc_rule, media_component);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
rx_message->result_code =
|
||||
RX_DIAMETER_REQUESTED_SERVICE_NOT_AUTHORIZED;
|
||||
ogs_error("update_qos() failed");
|
||||
|
@ -854,8 +800,7 @@ int pcrf_gx_send_rar(
|
|||
if (pcc_rule->qos.gbr.uplink == 0)
|
||||
pcc_rule->qos.gbr.uplink = db_pcc_rule->qos.gbr.uplink;
|
||||
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
if (charging_rule == 0) {
|
||||
ret = fd_msg_avp_new(gx_charging_rule_install, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
charging_rule = 1;
|
||||
|
@ -865,23 +810,18 @@ int pcrf_gx_send_rar(
|
|||
ogs_assert(rv == OGS_OK);
|
||||
}
|
||||
|
||||
if (charging_rule == 1)
|
||||
{
|
||||
if (charging_rule == 1) {
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
}
|
||||
else if (rx_message->cmd_code == RX_CMD_CODE_SESSION_TERMINATION)
|
||||
{
|
||||
} else if (rx_message->cmd_code == RX_CMD_CODE_SESSION_TERMINATION) {
|
||||
ogs_assert(rx_sess_data);
|
||||
|
||||
for (i = 0; i < rx_sess_data->num_of_pcc_rule; i++)
|
||||
{
|
||||
for (i = 0; i < rx_sess_data->num_of_pcc_rule; i++) {
|
||||
ogs_assert(rx_sess_data->pcc_rule[i].name);
|
||||
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
if (charging_rule == 0) {
|
||||
ret = fd_msg_avp_new(gx_charging_rule_remove, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
charging_rule = 1;
|
||||
|
@ -897,19 +837,16 @@ int pcrf_gx_send_rar(
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (charging_rule == 1)
|
||||
{
|
||||
if (charging_rule == 1) {
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
remove_rx_state(rx_sess_data);
|
||||
}
|
||||
else
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
if (charging_rule == 0) {
|
||||
rx_message->result_code = ER_DIAMETER_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1026,31 +963,24 @@ static void pcrf_gx_raa_cb(void *data, struct msg **msg)
|
|||
/* Value of Result Code */
|
||||
ret = fd_msg_search_avp(*msg, fd_result_code, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Result Code: %d", hdr->avp_value->i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_msg_search_avp(*msg, fd_experimental_result, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, fd_experimental_result_code, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Experimental Result Code: %d", result_code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no Result-Code");
|
||||
error++;
|
||||
}
|
||||
|
@ -1059,15 +989,12 @@ static void pcrf_gx_raa_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Host */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_host, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" From '%.*s'",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Host");
|
||||
error++;
|
||||
}
|
||||
|
@ -1075,15 +1002,12 @@ static void pcrf_gx_raa_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Realm */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_realm, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" ('%.*s')",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Realm");
|
||||
error++;
|
||||
}
|
||||
|
@ -1092,8 +1016,7 @@ static void pcrf_gx_raa_cb(void *data, struct msg **msg)
|
|||
ogs_assert(pthread_mutex_lock(&fd_logger_self()->stats_lock) == 0);
|
||||
dur = ((ts.tv_sec - sess_data->ts.tv_sec) * 1000000) +
|
||||
((ts.tv_nsec - sess_data->ts.tv_nsec) / 1000);
|
||||
if (fd_logger_self()->stats.nb_recv)
|
||||
{
|
||||
if (fd_logger_self()->stats.nb_recv) {
|
||||
/* Ponderate in the avg */
|
||||
fd_logger_self()->stats.avg = (fd_logger_self()->stats.avg *
|
||||
fd_logger_self()->stats.nb_recv + dur) /
|
||||
|
@ -1103,9 +1026,7 @@ static void pcrf_gx_raa_cb(void *data, struct msg **msg)
|
|||
fd_logger_self()->stats.shortest = dur;
|
||||
if (dur > fd_logger_self()->stats.longest)
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fd_logger_self()->stats.shortest = dur;
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
fd_logger_self()->stats.avg = dur;
|
||||
|
@ -1204,10 +1125,8 @@ static int encode_pcc_rule_definition(
|
|||
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (flow_presence == 1)
|
||||
{
|
||||
for (i = 0; i < pcc_rule->num_of_flow; i++)
|
||||
{
|
||||
if (flow_presence == 1) {
|
||||
for (i = 0; i < pcc_rule->num_of_flow; i++) {
|
||||
flow_t *flow = &pcc_rule->flow[i];
|
||||
|
||||
ret = fd_msg_avp_new(gx_flow_information, 0, &avpch2);
|
||||
|
@ -1284,8 +1203,7 @@ static int encode_pcc_rule_definition(
|
|||
ret = fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (pcc_rule->qos.mbr.uplink)
|
||||
{
|
||||
if (pcc_rule->qos.mbr.uplink) {
|
||||
ret = fd_msg_avp_new(gx_max_requested_bandwidth_ul, 0, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
val.u32 = pcc_rule->qos.mbr.uplink;
|
||||
|
@ -1295,8 +1213,7 @@ static int encode_pcc_rule_definition(
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (pcc_rule->qos.mbr.downlink)
|
||||
{
|
||||
if (pcc_rule->qos.mbr.downlink) {
|
||||
ret = fd_msg_avp_new(gx_max_requested_bandwidth_dl, 0, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
val.u32 = pcc_rule->qos.mbr.downlink;
|
||||
|
@ -1306,8 +1223,7 @@ static int encode_pcc_rule_definition(
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (pcc_rule->qos.gbr.uplink)
|
||||
{
|
||||
if (pcc_rule->qos.gbr.uplink) {
|
||||
ret = fd_msg_avp_new(gx_guaranteed_bitrate_ul, 0, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
val.u32 = pcc_rule->qos.gbr.uplink;
|
||||
|
@ -1317,8 +1233,7 @@ static int encode_pcc_rule_definition(
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (pcc_rule->qos.gbr.downlink)
|
||||
{
|
||||
if (pcc_rule->qos.gbr.downlink) {
|
||||
ret = fd_msg_avp_new(gx_guaranteed_bitrate_dl, 0, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
val.u32 = pcc_rule->qos.gbr.downlink;
|
||||
|
@ -1353,17 +1268,14 @@ static int flow_rx_to_gx(flow_t *rx_flow, flow_t *gx_flow)
|
|||
ogs_assert(gx_flow);
|
||||
|
||||
if (!strncmp(rx_flow->description,
|
||||
"permit out", strlen("permit out")))
|
||||
{
|
||||
"permit out", strlen("permit out"))) {
|
||||
gx_flow->direction = FLOW_DOWNLINK_ONLY;
|
||||
|
||||
len = strlen(rx_flow->description)+1;
|
||||
gx_flow->description = ogs_malloc(len);
|
||||
ogs_cpystrn(gx_flow->description, rx_flow->description, len);
|
||||
}
|
||||
else if (!strncmp(rx_flow->description,
|
||||
"permit in", strlen("permit in")))
|
||||
{
|
||||
} else if (!strncmp(rx_flow->description,
|
||||
"permit in", strlen("permit in"))) {
|
||||
gx_flow->direction = FLOW_UPLINK_ONLY;
|
||||
|
||||
/* 'permit in' should be changed
|
||||
|
@ -1374,9 +1286,7 @@ static int flow_rx_to_gx(flow_t *rx_flow, flow_t *gx_flow)
|
|||
strcat(gx_flow->description,
|
||||
&rx_flow->description[strlen("permit in")]);
|
||||
ogs_assert(len == strlen(gx_flow->description)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("Invalid Flow Descripton : [%s]", rx_flow->description);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
@ -1395,53 +1305,44 @@ static int matched_flow(
|
|||
ogs_assert(pcc_rule);
|
||||
ogs_assert(media_component);
|
||||
|
||||
for (i = 0; i < media_component->num_of_sub; i++)
|
||||
{
|
||||
for (i = 0; i < media_component->num_of_sub; i++) {
|
||||
rx_media_sub_component_t *sub = &media_component->sub[i];
|
||||
|
||||
if (sub->flow_number == 0)
|
||||
{
|
||||
if (sub->flow_number == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < sub->num_of_flow; j++)
|
||||
{
|
||||
for (j = 0; j < sub->num_of_flow; j++) {
|
||||
new++;
|
||||
}
|
||||
}
|
||||
|
||||
if (new == 0)
|
||||
{
|
||||
if (new == 0) {
|
||||
/* No new flow in Media-Component */
|
||||
return pcc_rule->num_of_flow;
|
||||
}
|
||||
|
||||
for (i = 0; i < media_component->num_of_sub; i++)
|
||||
{
|
||||
for (i = 0; i < media_component->num_of_sub; i++) {
|
||||
rx_media_sub_component_t *sub = &media_component->sub[i];
|
||||
|
||||
if (sub->flow_number == 0)
|
||||
{
|
||||
if (sub->flow_number == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < sub->num_of_flow; j++)
|
||||
{
|
||||
for (j = 0; j < sub->num_of_flow; j++) {
|
||||
flow_t gx_flow;
|
||||
flow_t *rx_flow = &sub->flow[j];
|
||||
|
||||
rv = flow_rx_to_gx(rx_flow, &gx_flow);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("flow reformatting error");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
for (k = 0; k < pcc_rule->num_of_flow; k++)
|
||||
{
|
||||
for (k = 0; k < pcc_rule->num_of_flow; k++) {
|
||||
if (gx_flow.direction == pcc_rule->flow[k].direction &&
|
||||
!strcmp(gx_flow.description, pcc_rule->flow[k].description))
|
||||
{
|
||||
!strcmp(gx_flow.description,
|
||||
pcc_rule->flow[k].description)) {
|
||||
matched++;
|
||||
break;
|
||||
}
|
||||
|
@ -1464,30 +1365,25 @@ static int install_flow(
|
|||
ogs_assert(media_component);
|
||||
|
||||
/* Remove Flow from PCC Rule */
|
||||
for (i = 0; i < pcc_rule->num_of_flow; i++)
|
||||
{
|
||||
for (i = 0; i < pcc_rule->num_of_flow; i++) {
|
||||
FLOW_FREE(&pcc_rule->flow[i]);
|
||||
}
|
||||
pcc_rule->num_of_flow = 0;
|
||||
|
||||
for (i = 0; i < media_component->num_of_sub; i++)
|
||||
{
|
||||
for (i = 0; i < media_component->num_of_sub; i++) {
|
||||
rx_media_sub_component_t *sub = &media_component->sub[i];
|
||||
|
||||
if (sub->flow_number == 0)
|
||||
{
|
||||
if (sub->flow_number == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy Flow to PCC Rule */
|
||||
for (j = 0; j < sub->num_of_flow; j++)
|
||||
{
|
||||
for (j = 0; j < sub->num_of_flow; j++) {
|
||||
flow_t *rx_flow = &sub->flow[j];
|
||||
flow_t *gx_flow = &pcc_rule->flow[pcc_rule->num_of_flow];
|
||||
|
||||
rv = flow_rx_to_gx(rx_flow, gx_flow);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("flow reformatting error");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
@ -1513,142 +1409,112 @@ static int update_qos(
|
|||
pcc_rule->qos.gbr.downlink = 0;
|
||||
pcc_rule->qos.gbr.uplink = 0;
|
||||
|
||||
for (i = 0; i < media_component->num_of_sub; i++)
|
||||
{
|
||||
for (i = 0; i < media_component->num_of_sub; i++) {
|
||||
rx_media_sub_component_t *sub = &media_component->sub[i];
|
||||
|
||||
if (sub->flow_number == 0)
|
||||
{
|
||||
if (sub->flow_number == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < sub->num_of_flow; j++)
|
||||
{
|
||||
for (j = 0; j < sub->num_of_flow; j++) {
|
||||
flow_t gx_flow;
|
||||
flow_t *rx_flow = &sub->flow[j];
|
||||
|
||||
rv = flow_rx_to_gx(rx_flow, &gx_flow);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("flow reformatting error");
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
if (gx_flow.direction == FLOW_DOWNLINK_ONLY)
|
||||
{
|
||||
if (sub->flow_usage == RX_FLOW_USAGE_RTCP)
|
||||
{
|
||||
if (gx_flow.direction == FLOW_DOWNLINK_ONLY) {
|
||||
if (sub->flow_usage == RX_FLOW_USAGE_RTCP) {
|
||||
if (media_component->rr_bandwidth &&
|
||||
media_component->rs_bandwidth)
|
||||
{
|
||||
media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
(media_component->rr_bandwidth +
|
||||
media_component->rs_bandwidth);
|
||||
}
|
||||
else if (media_component->max_requested_bandwidth_dl)
|
||||
{
|
||||
} else if (media_component->max_requested_bandwidth_dl) {
|
||||
if (media_component->rr_bandwidth &&
|
||||
!media_component->rs_bandwidth)
|
||||
{
|
||||
!media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
ogs_max(0.05 *
|
||||
media_component->max_requested_bandwidth_dl,
|
||||
media_component->rr_bandwidth);
|
||||
}
|
||||
if (!media_component->rr_bandwidth &&
|
||||
media_component->rs_bandwidth)
|
||||
{
|
||||
media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
ogs_max(0.05 *
|
||||
media_component->max_requested_bandwidth_dl,
|
||||
media_component->rs_bandwidth);
|
||||
}
|
||||
if (!media_component->rr_bandwidth &&
|
||||
!media_component->rs_bandwidth)
|
||||
{
|
||||
!media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
0.05 *
|
||||
media_component->max_requested_bandwidth_dl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gx_flow.description)
|
||||
{
|
||||
} else {
|
||||
if (gx_flow.description) {
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
media_component->max_requested_bandwidth_dl;
|
||||
pcc_rule->qos.gbr.downlink +=
|
||||
media_component->min_requested_bandwidth_dl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (gx_flow.direction == FLOW_UPLINK_ONLY)
|
||||
{
|
||||
if (sub->flow_usage == RX_FLOW_USAGE_RTCP)
|
||||
{
|
||||
} else if (gx_flow.direction == FLOW_UPLINK_ONLY) {
|
||||
if (sub->flow_usage == RX_FLOW_USAGE_RTCP) {
|
||||
if (media_component->rr_bandwidth &&
|
||||
media_component->rs_bandwidth)
|
||||
{
|
||||
media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
(media_component->rr_bandwidth +
|
||||
media_component->rs_bandwidth);
|
||||
}
|
||||
else if (media_component->max_requested_bandwidth_ul)
|
||||
{
|
||||
} else if (media_component->max_requested_bandwidth_ul) {
|
||||
if (media_component->rr_bandwidth &&
|
||||
!media_component->rs_bandwidth)
|
||||
{
|
||||
!media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
ogs_max(0.05 *
|
||||
media_component->max_requested_bandwidth_ul,
|
||||
media_component->rr_bandwidth);
|
||||
}
|
||||
if (!media_component->rr_bandwidth &&
|
||||
media_component->rs_bandwidth)
|
||||
{
|
||||
media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
ogs_max(0.05 *
|
||||
media_component->max_requested_bandwidth_ul,
|
||||
media_component->rs_bandwidth);
|
||||
}
|
||||
if (!media_component->rr_bandwidth &&
|
||||
!media_component->rs_bandwidth)
|
||||
{
|
||||
!media_component->rs_bandwidth) {
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
0.05 *
|
||||
media_component->max_requested_bandwidth_ul;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gx_flow.description)
|
||||
{
|
||||
} else {
|
||||
if (gx_flow.description) {
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
media_component->max_requested_bandwidth_ul;
|
||||
pcc_rule->qos.gbr.uplink +=
|
||||
media_component->min_requested_bandwidth_ul;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
FLOW_FREE(&gx_flow);
|
||||
}
|
||||
}
|
||||
|
||||
if (pcc_rule->qos.mbr.downlink == 0)
|
||||
{
|
||||
if (pcc_rule->qos.mbr.downlink == 0) {
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
media_component->max_requested_bandwidth_dl;
|
||||
pcc_rule->qos.mbr.downlink +=
|
||||
(media_component->rr_bandwidth + media_component->rs_bandwidth);
|
||||
}
|
||||
|
||||
if (pcc_rule->qos.mbr.uplink == 0)
|
||||
{
|
||||
if (pcc_rule->qos.mbr.uplink == 0) {
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
media_component->max_requested_bandwidth_ul;
|
||||
pcc_rule->qos.mbr.uplink +=
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fd/fd-lib.h"
|
||||
#include "fd/rx/rx-dict.h"
|
||||
#include "fd/rx/rx-message.h"
|
||||
|
@ -86,8 +105,7 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
ret = fd_sess_state_retrieve(pcrf_rx_reg, sess, &sess_data);
|
||||
ogs_assert(ret == 0);
|
||||
if (!sess_data)
|
||||
{
|
||||
if (!sess_data) {
|
||||
os0_t sid = NULL;
|
||||
ret = fd_sess_getsid(sess, &sid, &sidlen);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -127,25 +145,21 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get Framed-IP-Address */
|
||||
ret = fd_msg_search_avp(qry, rx_framed_ip_address, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_sid = (os0_t)pcrf_sess_find_by_ipv4(hdr->avp_value->os.data);
|
||||
if (!gx_sid)
|
||||
{
|
||||
if (!gx_sid) {
|
||||
ogs_warn("Cannot find Gx Sesson for IPv4:%s",
|
||||
INET_NTOP(hdr->avp_value->os.data, buf));
|
||||
}
|
||||
}
|
||||
|
||||
if (!gx_sid)
|
||||
{
|
||||
if (!gx_sid) {
|
||||
/* Get Framed-IPv6-Prefix */
|
||||
ret = fd_msg_search_avp(qry, rx_framed_ipv6_prefix, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
paa_t *paa = NULL;
|
||||
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
|
@ -154,190 +168,154 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
ogs_assert(paa);
|
||||
ogs_assert(paa->len == IPV6_LEN * 8 /* 128bit */);
|
||||
gx_sid = (os0_t)pcrf_sess_find_by_ipv6(paa->addr6);
|
||||
if (!gx_sid)
|
||||
{
|
||||
if (!gx_sid) {
|
||||
ogs_warn("Cannot find Gx Sesson for IPv6:%s",
|
||||
INET6_NTOP(hdr->avp_value->os.data, buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gx_sid)
|
||||
{
|
||||
if (!gx_sid) {
|
||||
ogs_error("No Gx Session");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch1)
|
||||
{
|
||||
while (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
switch(hdr->avp_code) {
|
||||
case AC_SESSION_ID:
|
||||
case AC_ORIGIN_HOST:
|
||||
if (sess_data->peer_host)
|
||||
ogs_free(sess_data->peer_host);
|
||||
sess_data->peer_host =
|
||||
(os0_t)ogs_strdup((char *)hdr->avp_value->os.data);
|
||||
ogs_assert(sess_data->peer_host);
|
||||
break;
|
||||
case AC_ORIGIN_REALM:
|
||||
case AC_DESTINATION_REALM:
|
||||
case AC_ROUTE_RECORD:
|
||||
case AC_PROXY_INFO:
|
||||
case AC_AUTH_APPLICATION_ID:
|
||||
case FD_AVP_CODE_FRAME_IP_ADDRESS:
|
||||
case FD_AVP_CODE_FRAME_IPV6_PREFIX:
|
||||
case RX_AVP_CODE_SUBSCRIPTION_ID:
|
||||
break;
|
||||
/* Gwt Specific-Action */
|
||||
case RX_AVP_CODE_SPECIFIC_ACTION:
|
||||
break;
|
||||
/* Gwt Media-Component-Description */
|
||||
case RX_AVP_CODE_MEDIA_COMPONENT_DESCRIPTION:
|
||||
{
|
||||
case AC_SESSION_ID:
|
||||
case AC_ORIGIN_HOST:
|
||||
{
|
||||
if (sess_data->peer_host)
|
||||
ogs_free(sess_data->peer_host);
|
||||
sess_data->peer_host =
|
||||
(os0_t)ogs_strdup((char *)hdr->avp_value->os.data);
|
||||
ogs_assert(sess_data->peer_host);
|
||||
break;
|
||||
}
|
||||
case AC_ORIGIN_REALM:
|
||||
case AC_DESTINATION_REALM:
|
||||
case AC_ROUTE_RECORD:
|
||||
case AC_PROXY_INFO:
|
||||
case AC_AUTH_APPLICATION_ID:
|
||||
case FD_AVP_CODE_FRAME_IP_ADDRESS:
|
||||
case FD_AVP_CODE_FRAME_IPV6_PREFIX:
|
||||
case RX_AVP_CODE_SUBSCRIPTION_ID:
|
||||
break;
|
||||
/* Gwt Specific-Action */
|
||||
case RX_AVP_CODE_SPECIFIC_ACTION:
|
||||
break;
|
||||
/* Gwt Media-Component-Description */
|
||||
case RX_AVP_CODE_MEDIA_COMPONENT_DESCRIPTION:
|
||||
{
|
||||
rx_media_component_t *media_component = &rx_message.
|
||||
media_component[rx_message.num_of_media_component];
|
||||
rx_media_component_t *media_component = &rx_message.
|
||||
media_component[rx_message.num_of_media_component];
|
||||
|
||||
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
|
||||
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch2)
|
||||
switch (hdr->avp_code) {
|
||||
case RX_AVP_CODE_MEDIA_COMPONENT_NUMBER:
|
||||
media_component->media_component_number =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_MEDIA_TYPE:
|
||||
media_component->media_type = hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_DL:
|
||||
media_component->max_requested_bandwidth_dl =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_UL:
|
||||
media_component->max_requested_bandwidth_ul =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_RR_BANDWIDTH:
|
||||
media_component->rr_bandwidth = hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_RS_BANDWIDTH:
|
||||
media_component->rs_bandwidth = hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_DL:
|
||||
media_component->min_requested_bandwidth_dl =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_UL:
|
||||
media_component->min_requested_bandwidth_ul =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_MEDIA_SUB_COMPONENT:
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
rx_media_sub_component_t *sub = &media_component->
|
||||
sub[media_component->num_of_sub];
|
||||
|
||||
ret = fd_msg_browse(avpch2, MSG_BRW_FIRST_CHILD,
|
||||
&avpch3, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case RX_AVP_CODE_MEDIA_COMPONENT_NUMBER:
|
||||
{
|
||||
media_component->media_component_number =
|
||||
while (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch (hdr->avp_code) {
|
||||
case RX_AVP_CODE_FLOW_NUMBER:
|
||||
sub->flow_number =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MEDIA_TYPE:
|
||||
{
|
||||
media_component->media_type = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_DL:
|
||||
{
|
||||
media_component->max_requested_bandwidth_dl =
|
||||
case RX_AVP_CODE_FLOW_USAGE:
|
||||
sub->flow_usage =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_UL:
|
||||
case RX_AVP_CODE_FLOW_DESCRIPTION:
|
||||
{
|
||||
media_component->max_requested_bandwidth_ul =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_RR_BANDWIDTH:
|
||||
{
|
||||
media_component->rr_bandwidth = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_RS_BANDWIDTH:
|
||||
{
|
||||
media_component->rs_bandwidth = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_DL:
|
||||
{
|
||||
media_component->min_requested_bandwidth_dl =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_UL:
|
||||
{
|
||||
media_component->min_requested_bandwidth_ul =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MEDIA_SUB_COMPONENT:
|
||||
{
|
||||
rx_media_sub_component_t *sub = &media_component->
|
||||
sub[media_component->num_of_sub];
|
||||
flow_t *flow = &sub->flow
|
||||
[sub->num_of_flow];
|
||||
|
||||
ret = fd_msg_browse(avpch2, MSG_BRW_FIRST_CHILD,
|
||||
&avpch3, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case RX_AVP_CODE_FLOW_NUMBER:
|
||||
sub->flow_number =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_FLOW_USAGE:
|
||||
{
|
||||
sub->flow_usage =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_FLOW_DESCRIPTION:
|
||||
{
|
||||
flow_t *flow = &sub->flow
|
||||
[sub->num_of_flow];
|
||||
flow->description = ogs_malloc(
|
||||
hdr->avp_value->os.len+1);
|
||||
ogs_cpystrn(
|
||||
flow->description,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
hdr->avp_value->os.len+1);
|
||||
|
||||
flow->description = ogs_malloc(
|
||||
hdr->avp_value->os.len+1);
|
||||
ogs_cpystrn(
|
||||
flow->description,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
hdr->avp_value->os.len+1);
|
||||
|
||||
sub->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not supported(%d)",
|
||||
hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch3, MSG_BRW_NEXT, &avpch3, NULL);
|
||||
}
|
||||
|
||||
media_component->num_of_sub++;
|
||||
sub->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
ogs_error("Not supported(%d)",
|
||||
hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch3, MSG_BRW_NEXT, &avpch3, NULL);
|
||||
}
|
||||
|
||||
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
|
||||
media_component->num_of_sub++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
|
||||
rx_message.num_of_media_component++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
|
||||
}
|
||||
|
||||
rx_message.num_of_media_component++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
|
||||
/* Send Re-Auth Request */
|
||||
rv = pcrf_gx_send_rar(gx_sid, sess_data->rx_sid, &rx_message);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
result_code = rx_message.result_code;
|
||||
if (result_code != ER_DIAMETER_SUCCESS)
|
||||
{
|
||||
if (result_code != ER_DIAMETER_SUCCESS) {
|
||||
ogs_error("pcrf_gx_send_rar() failed");
|
||||
goto out;
|
||||
}
|
||||
|
@ -391,26 +369,19 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
return 0;
|
||||
|
||||
out:
|
||||
if (result_code == FD_DIAMETER_AVP_UNSUPPORTED)
|
||||
{
|
||||
if (result_code == FD_DIAMETER_AVP_UNSUPPORTED) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_AVP_UNSUPPORTED", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID)
|
||||
{
|
||||
} else if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_UNKNOWN_SESSION_ID", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (result_code == FD_DIAMETER_MISSING_AVP)
|
||||
{
|
||||
} else if (result_code == FD_DIAMETER_MISSING_AVP) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_MISSING_AVP", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_message_experimental_rescode_set(ans, result_code);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
@ -554,32 +525,25 @@ static void pcrf_rx_asa_cb(void *data, struct msg **msg)
|
|||
/* Value of Result Code */
|
||||
ret = fd_msg_search_avp(*msg, fd_result_code, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Result Code: %d", hdr->avp_value->i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_msg_search_avp(*msg, fd_experimental_result, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, fd_experimental_result_code, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Experimental Result Code: %d",
|
||||
result_code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no Result-Code");
|
||||
}
|
||||
}
|
||||
|
@ -587,35 +551,28 @@ static void pcrf_rx_asa_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Host */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_host, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" From '%.*s'",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Host ");
|
||||
}
|
||||
|
||||
/* Value of Origin-Realm */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_realm, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" ('%.*s')",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Realm ");
|
||||
}
|
||||
|
||||
if (result_code != ER_DIAMETER_SUCCESS)
|
||||
{
|
||||
if (result_code != ER_DIAMETER_SUCCESS) {
|
||||
ogs_error("ERROR DIAMETER Result Code(%d)", result_code);
|
||||
}
|
||||
|
||||
|
@ -683,32 +640,26 @@ static int pcrf_rx_str_cb( struct msg **msg, struct avp *avp,
|
|||
/* Get Termination-Cause */
|
||||
ret = fd_msg_search_avp(qry, rx_termination_cause, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
sess_data->termination_cause = hdr->avp_value->i32;
|
||||
switch(sess_data->termination_cause)
|
||||
{
|
||||
case RX_TERMINATION_CAUSE_DIAMETER_LOGOUT:
|
||||
break;
|
||||
default:
|
||||
ogs_error("Termination-Cause Error : [%d]",
|
||||
sess_data->termination_cause);
|
||||
break;
|
||||
switch (sess_data->termination_cause) {
|
||||
case RX_TERMINATION_CAUSE_DIAMETER_LOGOUT:
|
||||
break;
|
||||
default:
|
||||
ogs_error("Termination-Cause Error : [%d]",
|
||||
sess_data->termination_cause);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Termination-Cause");
|
||||
}
|
||||
|
||||
if (sess_data->state != SESSION_ABORTED)
|
||||
{
|
||||
if (sess_data->state != SESSION_ABORTED) {
|
||||
/* Send Re-Auth Request if Abort-Session-Request is not initaited */
|
||||
rv = pcrf_gx_send_rar(sess_data->gx_sid, sess_data->rx_sid, &rx_message);
|
||||
if (rv != OGS_OK)
|
||||
{
|
||||
if (rv != OGS_OK) {
|
||||
result_code = rx_message.result_code;
|
||||
ogs_error("pcrf_gx_send_rar() failed");
|
||||
goto out;
|
||||
|
@ -736,26 +687,19 @@ static int pcrf_rx_str_cb( struct msg **msg, struct avp *avp,
|
|||
return 0;
|
||||
|
||||
out:
|
||||
if (result_code == FD_DIAMETER_AVP_UNSUPPORTED)
|
||||
{
|
||||
if (result_code == FD_DIAMETER_AVP_UNSUPPORTED) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_AVP_UNSUPPORTED", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID)
|
||||
{
|
||||
} else if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_UNKNOWN_SESSION_ID", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else if (result_code == FD_DIAMETER_MISSING_AVP)
|
||||
{
|
||||
} else if (result_code == FD_DIAMETER_MISSING_AVP) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_MISSING_AVP", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_MISSING_AVP", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
#include "gtp/gtp-xact.h"
|
||||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* This file is part of Open5GS.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gtp/gtp-xact.h"
|
||||
#include "fd/fd-lib.h"
|
||||
#include "fd/gx/gx-dict.h"
|
||||
#include "fd/gx/gx-message.h"
|
||||
|
@ -75,8 +93,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
ogs_assert(ret == 0);
|
||||
|
||||
/* Find Diameter Gx Session */
|
||||
if (sess->gx_sid)
|
||||
{
|
||||
if (sess->gx_sid) {
|
||||
/* Retrieve session by Session-Id */
|
||||
size_t sidlen = strlen(sess->gx_sid);
|
||||
ret = fd_sess_fromsid_msg((os0_t)sess->gx_sid, sidlen, &session, &new);
|
||||
|
@ -88,9 +105,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
ogs_assert(ret == 0);
|
||||
/* Save the session associated with the message */
|
||||
ret = fd_msg_sess_set(req, session);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* Create a new session */
|
||||
#define GX_APP_SID_OPT "app_gx"
|
||||
ret = fd_msg_new_session(req, (os0_t)GX_APP_SID_OPT,
|
||||
|
@ -102,8 +117,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
|
||||
/* Retrieve session state in this session */
|
||||
ret = fd_sess_state_retrieve(pgw_gx_reg, session, &sess_data);
|
||||
if (!sess_data)
|
||||
{
|
||||
if (!sess_data) {
|
||||
os0_t sid;
|
||||
size_t sidlen;
|
||||
|
||||
|
@ -194,8 +208,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST)
|
||||
{
|
||||
if (cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
|
||||
/* Set Supported-Features */
|
||||
ret = fd_msg_avp_new(gx_supported_features, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -229,8 +242,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
ogs_assert(ret == 0);
|
||||
|
||||
/* Set Framed-IP-Address */
|
||||
if (sess->ipv4)
|
||||
{
|
||||
if (sess->ipv4) {
|
||||
ret = fd_msg_avp_new(gx_framed_ip_address, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = (uint8_t*)&sess->ipv4->addr;
|
||||
|
@ -242,8 +254,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
}
|
||||
|
||||
/* Set Framed-IPv6-Prefix */
|
||||
if (sess->ipv6)
|
||||
{
|
||||
if (sess->ipv6) {
|
||||
ret = fd_msg_avp_new(gx_framed_ipv6_prefix, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
memcpy(&paa, &sess->pdn.paa, PAA_IPV6_LEN);
|
||||
|
@ -276,13 +287,11 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
ogs_assert(ret == 0);
|
||||
|
||||
/* Set QoS-Information */
|
||||
if (sess->pdn.ambr.downlink || sess->pdn.ambr.uplink)
|
||||
{
|
||||
if (sess->pdn.ambr.downlink || sess->pdn.ambr.uplink) {
|
||||
ret = fd_msg_avp_new(gx_qos_information, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
if (sess->pdn.ambr.uplink)
|
||||
{
|
||||
if (sess->pdn.ambr.uplink) {
|
||||
ret = fd_msg_avp_new(gx_apn_aggregate_max_bitrate_ul,
|
||||
0, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -293,8 +302,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
if (sess->pdn.ambr.downlink)
|
||||
{
|
||||
if (sess->pdn.ambr.downlink) {
|
||||
ret = fd_msg_avp_new(gx_apn_aggregate_max_bitrate_dl, 0,
|
||||
&avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
|
@ -382,8 +390,7 @@ void pgw_gx_send_ccr(pgw_sess_t *sess, gtp_xact_t *xact,
|
|||
}
|
||||
|
||||
/* Set 3GPP-MS-Timezone */
|
||||
if (message->create_session_request.ue_time_zone.presence)
|
||||
{
|
||||
if (message->create_session_request.ue_time_zone.presence) {
|
||||
ret = fd_msg_avp_new(gx_3gpp_ms_timezone, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = message->create_session_request.ue_time_zone.data;
|
||||
|
@ -482,32 +489,25 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
/* Value of Result Code */
|
||||
ret = fd_msg_search_avp(*msg, fd_result_code, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Result Code: %d", hdr->avp_value->i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_msg_search_avp(*msg, fd_experimental_result, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, fd_experimental_result_code, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->result_code = hdr->avp_value->i32;
|
||||
ogs_debug(" Experimental Result Code: %d",
|
||||
gx_message->result_code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no Result-Code");
|
||||
error++;
|
||||
}
|
||||
|
@ -516,15 +516,12 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Host */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_host, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" From '%.*s'",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Host");
|
||||
error++;
|
||||
}
|
||||
|
@ -532,55 +529,45 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
/* Value of Origin-Realm */
|
||||
ret = fd_msg_search_avp(*msg, fd_origin_realm, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_debug(" ('%.*s')",
|
||||
(int)hdr->avp_value->os.len, hdr->avp_value->os.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_Origin-Realm");
|
||||
error++;
|
||||
}
|
||||
|
||||
if (gx_message->result_code != ER_DIAMETER_SUCCESS)
|
||||
{
|
||||
if (gx_message->result_code != ER_DIAMETER_SUCCESS) {
|
||||
ogs_warn("ERROR DIAMETER Result Code(%d)", gx_message->result_code);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, gx_cc_request_type, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->cc_request_type = hdr->avp_value->i32;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ogs_error("no_CC-Request-Type");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, gx_qos_information, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, gx_apn_aggregate_max_bitrate_ul, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->pdn.ambr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avp, gx_apn_aggregate_max_bitrate_dl, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->pdn.ambr.downlink = hdr->avp_value->u32;
|
||||
|
@ -589,12 +576,10 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
|
||||
ret = fd_msg_search_avp(*msg, gx_default_eps_bearer_qos, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
if (avp)
|
||||
{
|
||||
if (avp) {
|
||||
ret = fd_avp_search_avp(avp, gx_qos_class_identifier, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->pdn.qos.qci = hdr->avp_value->u32;
|
||||
|
@ -602,12 +587,10 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
|
||||
ret = fd_avp_search_avp(avp, gx_allocation_retention_priority, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch1)
|
||||
{
|
||||
if (avpch1) {
|
||||
ret = fd_avp_search_avp(avpch1, gx_priority_level, &avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch2)
|
||||
{
|
||||
if (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->pdn.qos.arp.priority_level = hdr->avp_value->u32;
|
||||
|
@ -615,8 +598,7 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
|
||||
ret = fd_avp_search_avp(avpch1, gx_pre_emption_capability, &avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch2)
|
||||
{
|
||||
if (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->pdn.qos.arp.pre_emption_capability =
|
||||
|
@ -626,8 +608,7 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
ret = fd_avp_search_avp(avpch1,
|
||||
gx_pre_emption_vulnerability, &avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch2)
|
||||
{
|
||||
if (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
gx_message->pdn.qos.arp.pre_emption_vulnerability =
|
||||
|
@ -638,73 +619,62 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
|
||||
ret = fd_msg_browse(*msg, MSG_BRW_FIRST_CHILD, &avp, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avp)
|
||||
{
|
||||
while (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case AC_SESSION_ID:
|
||||
case AC_ORIGIN_HOST:
|
||||
case AC_ORIGIN_REALM:
|
||||
case AC_DESTINATION_REALM:
|
||||
case AC_RESULT_CODE:
|
||||
case AC_ROUTE_RECORD:
|
||||
case AC_PROXY_INFO:
|
||||
case AC_AUTH_APPLICATION_ID:
|
||||
break;
|
||||
case GX_AVP_CODE_CC_REQUEST_TYPE:
|
||||
case GX_AVP_CODE_CC_REQUEST_NUMBER:
|
||||
case GX_AVP_CODE_SUPPORTED_FEATURES:
|
||||
break;
|
||||
case GX_AVP_CODE_QOS_INFORMATION:
|
||||
case GX_AVP_CODE_DEFAULT_EPS_BEARER_QOS:
|
||||
break;
|
||||
case GX_AVP_CODE_CHARGING_RULE_INSTALL:
|
||||
{
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
switch (hdr->avp_code) {
|
||||
case AC_SESSION_ID:
|
||||
case AC_ORIGIN_HOST:
|
||||
case AC_ORIGIN_REALM:
|
||||
case AC_DESTINATION_REALM:
|
||||
case AC_RESULT_CODE:
|
||||
case AC_ROUTE_RECORD:
|
||||
case AC_PROXY_INFO:
|
||||
case AC_AUTH_APPLICATION_ID:
|
||||
break;
|
||||
case GX_AVP_CODE_CC_REQUEST_TYPE:
|
||||
case GX_AVP_CODE_CC_REQUEST_NUMBER:
|
||||
case GX_AVP_CODE_SUPPORTED_FEATURES:
|
||||
break;
|
||||
case GX_AVP_CODE_QOS_INFORMATION:
|
||||
case GX_AVP_CODE_DEFAULT_EPS_BEARER_QOS:
|
||||
break;
|
||||
case GX_AVP_CODE_CHARGING_RULE_INSTALL:
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch1)
|
||||
switch (hdr->avp_code) {
|
||||
case GX_AVP_CODE_CHARGING_RULE_DEFINITION:
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case GX_AVP_CODE_CHARGING_RULE_DEFINITION:
|
||||
{
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule
|
||||
[gx_message->num_of_pcc_rule];
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule
|
||||
[gx_message->num_of_pcc_rule];
|
||||
|
||||
rv = decode_pcc_rule_definition(
|
||||
pcc_rule, avpch1, &error);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
rv = decode_pcc_rule_definition(
|
||||
pcc_rule, avpch1, &error);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
pcc_rule->type = PCC_RULE_TYPE_INSTALL;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
pcc_rule->type = PCC_RULE_TYPE_INSTALL;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!error)
|
||||
{
|
||||
if (!error) {
|
||||
e = pgw_event_new(PGW_EVT_GX_MESSAGE);
|
||||
ogs_assert(e);
|
||||
|
||||
|
@ -722,9 +692,7 @@ out:
|
|||
} else {
|
||||
ogs_pollset_notify(pgw_self()->pollset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
gx_message_free(gx_message);
|
||||
ogs_pkbuf_free(gxbuf);
|
||||
ogs_pkbuf_free(gtpbuf);
|
||||
|
@ -734,8 +702,7 @@ out:
|
|||
ogs_assert(pthread_mutex_lock(&fd_logger_self()->stats_lock) == 0);
|
||||
dur = ((ts.tv_sec - sess_data->ts.tv_sec) * 1000000) +
|
||||
((ts.tv_nsec - sess_data->ts.tv_nsec) / 1000);
|
||||
if (fd_logger_self()->stats.nb_recv)
|
||||
{
|
||||
if (fd_logger_self()->stats.nb_recv) {
|
||||
/* Ponderate in the avg */
|
||||
fd_logger_self()->stats.avg = (fd_logger_self()->stats.avg *
|
||||
fd_logger_self()->stats.nb_recv + dur) /
|
||||
|
@ -745,9 +712,7 @@ out:
|
|||
fd_logger_self()->stats.shortest = dur;
|
||||
if (dur > fd_logger_self()->stats.longest)
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fd_logger_self()->stats.shortest = dur;
|
||||
fd_logger_self()->stats.longest = dur;
|
||||
fd_logger_self()->stats.avg = dur;
|
||||
|
@ -769,14 +734,11 @@ out:
|
|||
(int)(ts.tv_sec + 1 - sess_data->ts.tv_sec),
|
||||
(long)(1000000000 + ts.tv_nsec - sess_data->ts.tv_nsec) / 1000);
|
||||
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST)
|
||||
{
|
||||
if (sess_data->cc_request_type != GX_CC_REQUEST_TYPE_TERMINATION_REQUEST) {
|
||||
ret = fd_sess_state_store(pgw_gx_reg, session, &sess_data);
|
||||
ogs_assert(ret == 0);
|
||||
ogs_assert(sess_data == NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
state_cleanup(sess_data, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -839,8 +801,7 @@ static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
ret = fd_sess_state_retrieve(pgw_gx_reg, session, &sess_data);
|
||||
ogs_assert(ret == 0);
|
||||
if (!sess_data)
|
||||
{
|
||||
if (!sess_data) {
|
||||
ogs_error("No Session Data");
|
||||
goto out;
|
||||
}
|
||||
|
@ -851,94 +812,86 @@ static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
|||
|
||||
ret = fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avp)
|
||||
{
|
||||
while (avp) {
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
switch(hdr->avp_code) {
|
||||
case AC_SESSION_ID:
|
||||
case AC_ORIGIN_HOST:
|
||||
case AC_ORIGIN_REALM:
|
||||
case AC_DESTINATION_REALM:
|
||||
case AC_DESTINATION_HOST:
|
||||
case AC_ROUTE_RECORD:
|
||||
case AC_PROXY_INFO:
|
||||
case AC_AUTH_APPLICATION_ID:
|
||||
break;
|
||||
case GX_AVP_CODE_RE_AUTH_REQUEST_TYPE:
|
||||
break;
|
||||
case GX_AVP_CODE_CHARGING_RULE_INSTALL:
|
||||
{
|
||||
case AC_SESSION_ID:
|
||||
case AC_ORIGIN_HOST:
|
||||
case AC_ORIGIN_REALM:
|
||||
case AC_DESTINATION_REALM:
|
||||
case AC_DESTINATION_HOST:
|
||||
case AC_ROUTE_RECORD:
|
||||
case AC_PROXY_INFO:
|
||||
case AC_AUTH_APPLICATION_ID:
|
||||
break;
|
||||
case GX_AVP_CODE_RE_AUTH_REQUEST_TYPE:
|
||||
break;
|
||||
case GX_AVP_CODE_CHARGING_RULE_INSTALL:
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch1)
|
||||
{
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch1)
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
case GX_AVP_CODE_CHARGING_RULE_DEFINITION:
|
||||
{
|
||||
case GX_AVP_CODE_CHARGING_RULE_DEFINITION:
|
||||
{
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule
|
||||
[gx_message->num_of_pcc_rule];
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule
|
||||
[gx_message->num_of_pcc_rule];
|
||||
|
||||
rv = decode_pcc_rule_definition(
|
||||
pcc_rule, avpch1, NULL);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
rv = decode_pcc_rule_definition(
|
||||
pcc_rule, avpch1, NULL);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
pcc_rule->type = PCC_RULE_TYPE_INSTALL;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
pcc_rule->type = PCC_RULE_TYPE_INSTALL;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
break;
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
case GX_AVP_CODE_CHARGING_RULE_REMOVE:
|
||||
{
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_CHARGING_RULE_REMOVE:
|
||||
{
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch1)
|
||||
switch (hdr->avp_code) {
|
||||
case GX_AVP_CODE_CHARGING_RULE_NAME:
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
case GX_AVP_CODE_CHARGING_RULE_NAME:
|
||||
{
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule
|
||||
[gx_message->num_of_pcc_rule];
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule
|
||||
[gx_message->num_of_pcc_rule];
|
||||
|
||||
pcc_rule->name =
|
||||
ogs_strdup((char*)hdr->avp_value->os.data);
|
||||
ogs_assert(pcc_rule->name);
|
||||
pcc_rule->name =
|
||||
ogs_strdup((char*)hdr->avp_value->os.data);
|
||||
ogs_assert(pcc_rule->name);
|
||||
|
||||
pcc_rule->type = PCC_RULE_TYPE_REMOVE;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
pcc_rule->type = PCC_RULE_TYPE_REMOVE;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ogs_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL);
|
||||
}
|
||||
|
@ -991,14 +944,11 @@ static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
|||
return 0;
|
||||
|
||||
out:
|
||||
if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID)
|
||||
{
|
||||
if (result_code == FD_DIAMETER_UNKNOWN_SESSION_ID) {
|
||||
ret = fd_msg_rescode_set(ans,
|
||||
"DIAMETER_UNKNOWN_SESSION_ID", NULL, NULL, 1);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ret = fd_message_experimental_rescode_set(ans, result_code);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
@ -1079,179 +1029,148 @@ static int decode_pcc_rule_definition(
|
|||
|
||||
ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL);
|
||||
ogs_assert(ret == 0);
|
||||
while(avpch2)
|
||||
{
|
||||
while (avpch2) {
|
||||
ret = fd_msg_avp_hdr(avpch2, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
switch(hdr->avp_code)
|
||||
switch (hdr->avp_code) {
|
||||
case GX_AVP_CODE_CHARGING_RULE_NAME:
|
||||
if (pcc_rule->name)
|
||||
{
|
||||
ogs_error("PCC Rule Name has already been defined");
|
||||
ogs_free(pcc_rule->name);
|
||||
}
|
||||
pcc_rule->name = ogs_strdup((char*)hdr->avp_value->os.data);
|
||||
ogs_assert(pcc_rule->name);
|
||||
break;
|
||||
case GX_AVP_CODE_FLOW_INFORMATION:
|
||||
{
|
||||
case GX_AVP_CODE_CHARGING_RULE_NAME:
|
||||
{
|
||||
if (pcc_rule->name)
|
||||
{
|
||||
ogs_error("PCC Rule Name has already been defined");
|
||||
ogs_free(pcc_rule->name);
|
||||
}
|
||||
pcc_rule->name = ogs_strdup((char*)hdr->avp_value->os.data);
|
||||
ogs_assert(pcc_rule->name);
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_INFORMATION:
|
||||
{
|
||||
flow_t *flow =
|
||||
&pcc_rule->flow[pcc_rule->num_of_flow];
|
||||
flow_t *flow =
|
||||
&pcc_rule->flow[pcc_rule->num_of_flow];
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, gx_flow_direction, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr( avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
flow->direction = hdr->avp_value->i32;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, gx_flow_description, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
flow->description = ogs_malloc(hdr->avp_value->os.len+1);
|
||||
ogs_cpystrn(flow->description,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
hdr->avp_value->os.len+1);
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_STATUS:
|
||||
ret = fd_avp_search_avp(avpch2, gx_flow_direction, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
pcc_rule->flow_status = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_QOS_INFORMATION:
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_qos_class_identifier, &avpch3);
|
||||
ret = fd_msg_avp_hdr( avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
flow->direction = hdr->avp_value->i32;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2, gx_flow_description, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
flow->description = ogs_malloc(hdr->avp_value->os.len+1);
|
||||
ogs_cpystrn(flow->description,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
hdr->avp_value->os.len+1);
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
case GX_AVP_CODE_FLOW_STATUS:
|
||||
pcc_rule->flow_status = hdr->avp_value->i32;
|
||||
break;
|
||||
case GX_AVP_CODE_QOS_INFORMATION:
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_qos_class_identifier, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.qci = hdr->avp_value->u32;
|
||||
} else {
|
||||
ogs_error("no_QCI");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_allocation_retention_priority, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_avp_search_avp(avpch3, gx_priority_level, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.qci = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_QCI");
|
||||
pcc_rule->qos.arp.priority_level = hdr->avp_value->u32;
|
||||
} else {
|
||||
ogs_error("no_Priority-Level");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_allocation_retention_priority, &avpch3);
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_capability, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_avp_search_avp(avpch3, gx_priority_level, &avpch4);
|
||||
if (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.arp.priority_level = hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Priority-Level");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_capability, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.arp.pre_emption_capability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Preemption-Capability");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_vulnerability, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch4)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability =
|
||||
hdr->avp_value->u32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_Preemption-Vulnerability");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ogs_error("no_ARP");
|
||||
pcc_rule->qos.arp.pre_emption_capability =
|
||||
hdr->avp_value->u32;
|
||||
} else {
|
||||
ogs_error("no_Preemption-Capability");
|
||||
error++;
|
||||
}
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_ul, &avpch3);
|
||||
ret = fd_avp_search_avp(avpch3,
|
||||
gx_pre_emption_vulnerability, &avpch4);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
if (avpch4) {
|
||||
ret = fd_msg_avp_hdr(avpch4, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.mbr.uplink = hdr->avp_value->u32;
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability =
|
||||
hdr->avp_value->u32;
|
||||
} else {
|
||||
ogs_error("no_Preemption-Vulnerability");
|
||||
error++;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_dl, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.mbr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_ul, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.gbr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_dl, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.gbr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
ogs_error("no_ARP");
|
||||
error++;
|
||||
}
|
||||
case GX_AVP_CODE_PRECEDENCE:
|
||||
{
|
||||
pcc_rule->precedence = hdr->avp_value->i32;
|
||||
break;
|
||||
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_ul, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.mbr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ogs_error("Not implemented(%d)", hdr->avp_code);
|
||||
break;
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_max_requested_bandwidth_dl, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.mbr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_ul, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.gbr.uplink = hdr->avp_value->u32;
|
||||
}
|
||||
ret = fd_avp_search_avp(avpch2,
|
||||
gx_guaranteed_bitrate_dl, &avpch3);
|
||||
ogs_assert(ret == 0);
|
||||
if (avpch3) {
|
||||
ret = fd_msg_avp_hdr(avpch3, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
pcc_rule->qos.gbr.downlink = hdr->avp_value->u32;
|
||||
}
|
||||
break;
|
||||
case GX_AVP_CODE_PRECEDENCE:
|
||||
pcc_rule->precedence = hdr->avp_value->i32;
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not implemented(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch2, MSG_BRW_NEXT, &avpch2, NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue