change code indentation

This commit is contained in:
Sukchan Lee 2019-06-11 23:16:54 +09:00
parent c530e1cbcf
commit f28f3003c5
6 changed files with 893 additions and 1247 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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"

View File

@ -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 +=

View File

@ -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);

View File

@ -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);
}