open5gs/src/pcrf/pcrf_context.c

769 lines
33 KiB
C
Raw Normal View History

2017-08-17 05:15:08 +00:00
#include <mongoc.h>
2017-11-29 00:51:34 +00:00
#include <yaml.h>
2017-08-17 05:15:08 +00:00
2019-06-11 09:28:25 +00:00
#include "fd/fd-lib.h"
2017-08-17 05:15:08 +00:00
2019-04-27 14:54:30 +00:00
#include "app/context.h"
2017-08-17 05:15:08 +00:00
#include "pcrf_context.h"
static pcrf_context_t self;
static fd_config_t g_fd_conf;
2019-04-27 14:54:30 +00:00
int __pcrf_log_domain;
2017-08-17 05:15:08 +00:00
static int context_initialized = 0;
pcrf_context_t* pcrf_self()
{
return &self;
}
2019-05-06 11:43:50 +00:00
void pcrf_context_init(void)
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_assert(context_initialized == 0);
2017-08-17 05:15:08 +00:00
/* Initial FreeDiameter Config */
memset(&g_fd_conf, 0, sizeof(fd_config_t));
2017-08-17 05:15:08 +00:00
/* Initialize PCRF context */
memset(&self, 0, sizeof(pcrf_context_t));
self.fd_config = &g_fd_conf;
2017-08-17 05:15:08 +00:00
2019-04-27 14:54:30 +00:00
ogs_log_install_domain(&__pcrf_log_domain, "pcrf", ogs_core()->log.level);
ogs_thread_mutex_init(&self.db_lock);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_init(&self.hash_lock);
self.ip_hash = ogs_hash_make();
2017-08-17 05:15:08 +00:00
context_initialized = 1;
}
2019-05-06 11:43:50 +00:00
void pcrf_context_final(void)
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_assert(context_initialized == 1);
ogs_assert(self.ip_hash);
ogs_hash_destroy(self.ip_hash);
ogs_thread_mutex_destroy(&self.hash_lock);
2017-08-17 05:15:08 +00:00
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_destroy(&self.db_lock);
2017-08-17 05:15:08 +00:00
context_initialized = 0;
}
2019-04-27 14:54:30 +00:00
static int pcrf_context_prepare()
2017-08-17 05:15:08 +00:00
{
self.fd_config->cnf_port = DIAMETER_PORT;
self.fd_config->cnf_port_tls = DIAMETER_SECURE_PORT;
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-17 05:15:08 +00:00
}
2019-04-27 14:54:30 +00:00
static int pcrf_context_validation()
2017-08-17 05:15:08 +00:00
{
if (self.fd_conf_path == NULL &&
(self.fd_config->cnf_diamid == NULL ||
self.fd_config->cnf_diamrlm == NULL ||
self.fd_config->cnf_addr == NULL))
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_error("No pcrf.freeDiameter in '%s'",
2017-08-17 05:15:08 +00:00
context_self()->config.path);
2019-04-27 14:54:30 +00:00
return OGS_ERROR;
2017-08-17 05:15:08 +00:00
}
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-17 05:15:08 +00:00
}
2019-04-27 14:54:30 +00:00
int pcrf_context_parse_config()
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
int rv;
2017-08-17 05:15:08 +00:00
config_t *config = &context_self()->config;
2017-11-29 00:51:34 +00:00
yaml_document_t *document = NULL;
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_t root_iter;
2017-08-17 05:15:08 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(config);
2017-11-29 00:51:34 +00:00
document = config->document;
2019-04-27 14:54:30 +00:00
ogs_assert(document);
2017-08-17 05:15:08 +00:00
rv = pcrf_context_prepare();
2019-04-27 14:54:30 +00:00
if (rv != OGS_OK) return rv;
2017-08-17 05:15:08 +00:00
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_init(&root_iter, document);
while(ogs_yaml_iter_next(&root_iter))
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
const char *root_key = ogs_yaml_iter_key(&root_iter);
ogs_assert(root_key);
2017-11-29 00:51:34 +00:00
if (!strcmp(root_key, "pcrf"))
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_t pcrf_iter;
ogs_yaml_iter_recurse(&root_iter, &pcrf_iter);
while(ogs_yaml_iter_next(&pcrf_iter))
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
const char *pcrf_key = ogs_yaml_iter_key(&pcrf_iter);
ogs_assert(pcrf_key);
2017-11-29 00:51:34 +00:00
if (!strcmp(pcrf_key, "freeDiameter"))
2017-08-17 05:15:08 +00:00
{
yaml_node_t *node =
yaml_document_get_node(document, pcrf_iter.pair->value);
2019-04-27 14:54:30 +00:00
ogs_assert(node);
if (node->type == YAML_SCALAR_NODE)
{
2019-04-27 14:54:30 +00:00
self.fd_conf_path = ogs_yaml_iter_value(&pcrf_iter);
}
else if (node->type == YAML_MAPPING_NODE)
{
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_t fd_iter;
ogs_yaml_iter_recurse(&pcrf_iter, &fd_iter);
2019-04-27 14:54:30 +00:00
while(ogs_yaml_iter_next(&fd_iter))
{
2019-04-27 14:54:30 +00:00
const char *fd_key = ogs_yaml_iter_key(&fd_iter);
ogs_assert(fd_key);
if (!strcmp(fd_key, "identity"))
{
self.fd_config->cnf_diamid =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_value(&fd_iter);
}
else if (!strcmp(fd_key, "realm"))
{
self.fd_config->cnf_diamrlm =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_value(&fd_iter);
}
else if (!strcmp(fd_key, "port"))
{
2019-04-27 14:54:30 +00:00
const char *v = ogs_yaml_iter_value(&fd_iter);
if (v) self.fd_config->cnf_port = atoi(v);
}
else if (!strcmp(fd_key, "sec_port"))
{
2019-04-27 14:54:30 +00:00
const char *v = ogs_yaml_iter_value(&fd_iter);
if (v) self.fd_config->cnf_port_tls = atoi(v);
}
else if (!strcmp(fd_key, "no_sctp"))
{
self.fd_config->cnf_flags.no_sctp =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_bool(&fd_iter);
}
else if (!strcmp(fd_key, "listen_on"))
{
self.fd_config->cnf_addr =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_value(&fd_iter);
}
else if (!strcmp(fd_key, "load_extension"))
{
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_t ext_array, ext_iter;
ogs_yaml_iter_recurse(&fd_iter, &ext_array);
do
{
const char *module = NULL;
const char *conf = NULL;
2019-04-27 14:54:30 +00:00
if (ogs_yaml_iter_type(&ext_array) ==
YAML_MAPPING_NODE)
{
memcpy(&ext_iter, &ext_array,
2019-04-27 14:54:30 +00:00
sizeof(ogs_yaml_iter_t));
}
2019-04-27 14:54:30 +00:00
else if (ogs_yaml_iter_type(&ext_array) ==
YAML_SEQUENCE_NODE)
{
2019-04-27 14:54:30 +00:00
if (!ogs_yaml_iter_next(&ext_array))
break;
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_recurse(
&ext_array, &ext_iter);
}
2019-04-27 14:54:30 +00:00
else if (ogs_yaml_iter_type(&ext_array) ==
YAML_SCALAR_NODE)
{
break;
}
else
2019-04-27 14:54:30 +00:00
ogs_assert_if_reached();
2019-04-27 14:54:30 +00:00
while(ogs_yaml_iter_next(&ext_iter))
{
const char *ext_key =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_key(&ext_iter);
ogs_assert(ext_key);
if (!strcmp(ext_key, "module"))
{
2019-04-27 14:54:30 +00:00
module = ogs_yaml_iter_value(&ext_iter);
}
else if (!strcmp(ext_key, "conf"))
{
2019-04-27 14:54:30 +00:00
conf = ogs_yaml_iter_value(&ext_iter);
}
else
2019-04-27 14:54:30 +00:00
ogs_warn("unknown key `%s`", ext_key);
}
if (module)
{
self.fd_config->
ext[self.fd_config->num_of_ext].
module = module;
self.fd_config->
ext[self.fd_config->num_of_ext].
conf = conf;
self.fd_config->num_of_ext++;
}
2019-04-27 14:54:30 +00:00
} while(ogs_yaml_iter_type(&ext_array) ==
YAML_SEQUENCE_NODE);
}
else if (!strcmp(fd_key, "connect"))
{
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_t conn_array, conn_iter;
ogs_yaml_iter_recurse(&fd_iter, &conn_array);
do
{
const char *identity = NULL;
const char *addr = NULL;
2019-04-27 14:54:30 +00:00
uint16_t port = 0;
2019-04-27 14:54:30 +00:00
if (ogs_yaml_iter_type(&conn_array) ==
YAML_MAPPING_NODE)
{
memcpy(&conn_iter, &conn_array,
2019-04-27 14:54:30 +00:00
sizeof(ogs_yaml_iter_t));
}
2019-04-27 14:54:30 +00:00
else if (ogs_yaml_iter_type(&conn_array) ==
YAML_SEQUENCE_NODE)
{
2019-04-27 14:54:30 +00:00
if (!ogs_yaml_iter_next(&conn_array))
break;
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_recurse(&conn_array, &conn_iter);
}
2019-04-27 14:54:30 +00:00
else if (ogs_yaml_iter_type(&conn_array) ==
YAML_SCALAR_NODE)
{
break;
}
else
2019-04-27 14:54:30 +00:00
ogs_assert_if_reached();
2019-04-27 14:54:30 +00:00
while(ogs_yaml_iter_next(&conn_iter))
{
const char *conn_key =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_key(&conn_iter);
ogs_assert(conn_key);
if (!strcmp(conn_key, "identity"))
{
2019-04-27 14:54:30 +00:00
identity = ogs_yaml_iter_value(&conn_iter);
}
else if (!strcmp(conn_key, "addr"))
{
2019-04-27 14:54:30 +00:00
addr = ogs_yaml_iter_value(&conn_iter);
}
else if (!strcmp(conn_key, "port"))
{
const char *v =
2019-04-27 14:54:30 +00:00
ogs_yaml_iter_value(&conn_iter);
if (v) port = atoi(v);
}
else
2019-04-27 14:54:30 +00:00
ogs_warn("unknown key `%s`", conn_key);
}
if (identity && addr)
{
self.fd_config->
conn[self.fd_config->num_of_conn].
identity = identity;
self.fd_config->
conn[self.fd_config->num_of_conn].
addr = addr;
self.fd_config->
conn[self.fd_config->num_of_conn].
port = port;
self.fd_config->num_of_conn++;
}
2019-04-27 14:54:30 +00:00
} while(ogs_yaml_iter_type(&conn_array) ==
YAML_SEQUENCE_NODE);
}
else
2019-04-27 14:54:30 +00:00
ogs_warn("unknown key `%s`", fd_key);
}
}
2017-08-17 05:15:08 +00:00
}
2017-11-29 00:51:34 +00:00
else
2019-04-27 14:54:30 +00:00
ogs_warn("unknown key `%s`", pcrf_key);
2017-08-17 05:15:08 +00:00
}
}
}
rv = pcrf_context_validation();
2019-04-27 14:54:30 +00:00
if (rv != OGS_OK) return rv;
2017-08-17 05:15:08 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-17 05:15:08 +00:00
}
2019-04-27 14:54:30 +00:00
int pcrf_db_init()
2017-08-17 05:15:08 +00:00
{
2019-04-27 14:54:30 +00:00
if (context_self()->db.client && context_self()->db.name)
2017-08-17 05:15:08 +00:00
{
self.subscriberCollection = mongoc_client_get_collection(
2019-04-27 14:54:30 +00:00
context_self()->db.client,
context_self()->db.name, "subscribers");
ogs_assert(self.subscriberCollection);
2017-08-17 05:15:08 +00:00
}
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-17 05:15:08 +00:00
}
2019-04-27 14:54:30 +00:00
int pcrf_db_final()
2017-08-17 05:15:08 +00:00
{
if (self.subscriberCollection)
{
mongoc_collection_destroy(self.subscriberCollection);
}
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-17 05:15:08 +00:00
}
2017-08-24 08:05:10 +00:00
2019-04-27 14:54:30 +00:00
int pcrf_db_qos_data(char *imsi_bcd, char *apn, gx_message_t *gx_message)
2017-08-24 08:05:10 +00:00
{
2019-04-27 14:54:30 +00:00
int rv = OGS_OK;
2017-08-24 08:05:10 +00:00
mongoc_cursor_t *cursor = NULL;
bson_t *query = NULL;
bson_t *opts = NULL;
bson_error_t error;
const bson_t *document;
bson_iter_t iter;
bson_iter_t child1_iter, child2_iter, child3_iter;
bson_iter_t child4_iter, child5_iter, child6_iter;
const char *utf8 = NULL;
2019-04-27 14:54:30 +00:00
uint32_t length = 0;
2017-08-24 08:05:10 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(imsi_bcd);
ogs_assert(apn);
ogs_assert(gx_message);
2017-08-24 08:05:10 +00:00
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_lock(&self.db_lock);
2017-08-24 08:05:10 +00:00
query = BCON_NEW(
"imsi", BCON_UTF8(imsi_bcd),
"pdn.apn", BCON_UTF8(apn));
#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5
2017-08-24 08:05:10 +00:00
opts = BCON_NEW(
"projection", "{",
"imsi", BCON_INT64(1),
"pdn.$", BCON_INT64(1),
"}"
);
cursor = mongoc_collection_find_with_opts(
self.subscriberCollection, query, opts, NULL);
#else
opts = BCON_NEW(
"imsi", BCON_INT64(1),
"pdn.$", BCON_INT64(1)
);
cursor = mongoc_collection_find(self.subscriberCollection,
MONGOC_QUERY_NONE, 0, 0, 0, query, opts, NULL);
#endif
2017-08-24 08:05:10 +00:00
if (!mongoc_cursor_next(cursor, &document))
{
2019-04-27 14:54:30 +00:00
ogs_error("Cannot find IMSI(%s)+APN(%s) in DB", imsi_bcd, apn);
2017-08-24 08:05:10 +00:00
2019-04-27 14:54:30 +00:00
rv = OGS_ERROR;
2017-08-24 08:05:10 +00:00
goto out;
}
if (mongoc_cursor_error(cursor, &error))
{
2019-04-27 14:54:30 +00:00
ogs_error("Cursor Failure: %s", error.message);
2017-08-24 08:05:10 +00:00
2019-04-27 14:54:30 +00:00
rv = OGS_ERROR;
2017-08-24 08:05:10 +00:00
goto out;
}
if (!bson_iter_init(&iter, document))
{
2019-04-27 14:54:30 +00:00
ogs_error("bson_iter_init failed in this document");
2017-08-24 08:05:10 +00:00
2019-04-27 14:54:30 +00:00
rv = OGS_ERROR;
2017-08-24 08:05:10 +00:00
goto out;
}
while(bson_iter_next(&iter))
{
const char *key = bson_iter_key(&iter);
if (!strcmp(key, "pdn") &&
BSON_ITER_HOLDS_ARRAY(&iter))
{
int pdn_index = 0;
bson_iter_recurse(&iter, &child1_iter);
while(bson_iter_next(&child1_iter))
{
const char *child1_key = bson_iter_key(&child1_iter);
pdn_t *pdn = NULL;
2019-04-27 14:54:30 +00:00
ogs_assert(child1_key);
2017-08-24 08:05:10 +00:00
pdn_index = atoi(child1_key);
2019-04-27 14:54:30 +00:00
ogs_assert(pdn_index == 0);
2017-08-24 08:05:10 +00:00
2018-01-10 13:09:08 +00:00
pdn = &gx_message->pdn;
2017-08-24 08:05:10 +00:00
bson_iter_recurse(&child1_iter, &child2_iter);
while(bson_iter_next(&child2_iter))
{
const char *child2_key = bson_iter_key(&child2_iter);
if (!strcmp(child2_key, "apn") &&
BSON_ITER_HOLDS_UTF8(&child2_iter))
{
utf8 = bson_iter_utf8(&child2_iter, &length);
2019-04-27 14:54:30 +00:00
ogs_cpystrn(pdn->apn, utf8,
ogs_min(length, MAX_APN_LEN)+1);
2017-08-24 08:05:10 +00:00
}
else if (!strcmp(child2_key, "type") &&
BSON_ITER_HOLDS_INT32(&child2_iter))
{
pdn->pdn_type = bson_iter_int32(&child2_iter);
}
else if (!strcmp(child2_key, "qos") &&
BSON_ITER_HOLDS_DOCUMENT(&child2_iter))
{
bson_iter_recurse(&child2_iter, &child3_iter);
while(bson_iter_next(&child3_iter))
{
const char *child3_key =
bson_iter_key(&child3_iter);
if (!strcmp(child3_key, "qci") &&
BSON_ITER_HOLDS_INT32(&child3_iter))
{
pdn->qos.qci = bson_iter_int32(&child3_iter);
}
else if (!strcmp(child3_key, "arp") &&
BSON_ITER_HOLDS_DOCUMENT(&child3_iter))
{
bson_iter_recurse(&child3_iter, &child4_iter);
while(bson_iter_next(&child4_iter))
{
const char *child4_key =
bson_iter_key(&child4_iter);
if (!strcmp(child4_key, "priority_level") &&
BSON_ITER_HOLDS_INT32(&child4_iter))
{
pdn->qos.arp.priority_level =
bson_iter_int32(&child4_iter);
}
else if (!strcmp(child4_key,
"pre_emption_capability") &&
BSON_ITER_HOLDS_INT32(&child4_iter))
{
pdn->qos.arp.pre_emption_capability =
bson_iter_int32(&child4_iter);
}
else if (!strcmp(child4_key,
"pre_emption_vulnerability") &&
BSON_ITER_HOLDS_INT32(&child4_iter))
{
pdn->qos.arp.pre_emption_vulnerability =
bson_iter_int32(&child4_iter);
}
}
}
}
}
else if (!strcmp(child2_key, "ambr") &&
BSON_ITER_HOLDS_DOCUMENT(&child2_iter))
{
bson_iter_recurse(&child2_iter, &child3_iter);
while(bson_iter_next(&child3_iter))
{
const char *child3_key =
bson_iter_key(&child3_iter);
if (!strcmp(child3_key, "uplink") &&
BSON_ITER_HOLDS_INT64(&child3_iter))
2017-08-24 08:05:10 +00:00
{
pdn->ambr.uplink =
bson_iter_int64(&child3_iter) * 1024;
2017-08-24 08:05:10 +00:00
}
else if (!strcmp(child3_key, "downlink") &&
BSON_ITER_HOLDS_INT64(&child3_iter))
2017-08-24 08:05:10 +00:00
{
pdn->ambr.downlink =
bson_iter_int64(&child3_iter) * 1024;
2017-08-24 08:05:10 +00:00
}
}
}
else if (!strcmp(child2_key, "pcc_rule") &&
BSON_ITER_HOLDS_ARRAY(&child2_iter))
{
int pcc_rule_index = 0;
bson_iter_recurse(&child2_iter, &child3_iter);
while(bson_iter_next(&child3_iter))
{
const char *child3_key =
bson_iter_key(&child3_iter);
pcc_rule_t *pcc_rule = NULL;
2019-04-27 14:54:30 +00:00
ogs_assert(child3_key);
2017-08-24 08:05:10 +00:00
pcc_rule_index = atoi(child3_key);
2019-04-27 14:54:30 +00:00
ogs_assert(pcc_rule_index < MAX_NUM_OF_PCC_RULE);
2017-08-24 08:05:10 +00:00
2018-01-10 13:09:08 +00:00
pcc_rule = &gx_message->pcc_rule[pcc_rule_index];
2017-08-24 08:05:10 +00:00
bson_iter_recurse(&child3_iter, &child4_iter);
while(bson_iter_next(&child4_iter))
{
const char *child4_key =
bson_iter_key(&child4_iter);
if (!strcmp(child4_key, "qos") &&
BSON_ITER_HOLDS_DOCUMENT(&child4_iter))
{
bson_iter_recurse(
&child4_iter, &child5_iter);
while(bson_iter_next(&child5_iter))
{
const char *child5_key =
bson_iter_key(&child5_iter);
if (!strcmp(child5_key, "qci") &&
BSON_ITER_HOLDS_INT32(&child5_iter))
{
pcc_rule->qos.qci =
bson_iter_int32(&child5_iter);
}
else if (!strcmp(child5_key, "arp") &&
BSON_ITER_HOLDS_DOCUMENT(
&child5_iter))
{
bson_iter_recurse(
&child5_iter, &child6_iter);
while(bson_iter_next(&child6_iter))
{
const char *child6_key =
bson_iter_key(&child6_iter);
if (!strcmp(child6_key,
"priority_level") &&
BSON_ITER_HOLDS_INT32(
&child6_iter))
{
pcc_rule->qos.arp.
priority_level =
bson_iter_int32(
&child6_iter);
}
else if (!strcmp(child6_key,
"pre_emption_capability") &&
BSON_ITER_HOLDS_INT32(
&child6_iter))
{
pcc_rule->qos.arp.
pre_emption_capability =
bson_iter_int32(
&child6_iter);
}
else if (!strcmp(child6_key,
"pre_emption_vulnerability") &&
BSON_ITER_HOLDS_INT32(&child6_iter))
{
pcc_rule->qos.arp.
pre_emption_vulnerability =
bson_iter_int32(
&child6_iter);
}
}
}
else if (!strcmp(child5_key, "mbr") &&
BSON_ITER_HOLDS_DOCUMENT(
&child5_iter))
{
bson_iter_recurse(
&child5_iter, &child6_iter);
while(bson_iter_next(&child6_iter))
{
const char *child6_key =
bson_iter_key(&child6_iter);
if (!strcmp(child6_key,
"downlink") &&
BSON_ITER_HOLDS_INT64(
2017-08-24 08:05:10 +00:00
&child6_iter))
{
pcc_rule->qos.mbr.downlink =
bson_iter_int64(
2017-08-24 14:10:36 +00:00
&child6_iter) * 1024;
2017-08-24 08:05:10 +00:00
}
else if (!strcmp(child6_key,
"uplink") &&
BSON_ITER_HOLDS_INT64(
2017-08-24 08:05:10 +00:00
&child6_iter))
{
pcc_rule->qos.mbr.uplink =
bson_iter_int64(
2017-08-24 14:10:36 +00:00
&child6_iter) * 1024;
2017-08-24 08:05:10 +00:00
}
}
}
else if (!strcmp(child5_key, "gbr") &&
BSON_ITER_HOLDS_DOCUMENT(
&child5_iter))
{
bson_iter_recurse(&child5_iter,
&child6_iter);
while(bson_iter_next(&child6_iter))
{
const char *child6_key =
bson_iter_key(&child6_iter);
if (!strcmp(child6_key,
"downlink") &&
BSON_ITER_HOLDS_INT64(
2017-08-24 08:05:10 +00:00
&child6_iter))
{
pcc_rule->qos.gbr.downlink =
bson_iter_int64(
2017-08-24 14:10:36 +00:00
&child6_iter) * 1024;
2017-08-24 08:05:10 +00:00
}
else if (!strcmp(child6_key,
"uplink") &&
BSON_ITER_HOLDS_INT64(
2017-08-24 08:05:10 +00:00
&child6_iter))
{
pcc_rule->qos.gbr.uplink =
bson_iter_int64(
2017-08-24 14:10:36 +00:00
&child6_iter) * 1024;
2017-08-24 08:05:10 +00:00
}
}
}
}
}
else if (!strcmp(child4_key, "flow") &&
BSON_ITER_HOLDS_ARRAY(&child4_iter))
{
int flow_index = 0;
bson_iter_recurse(&child4_iter,
&child5_iter);
while(bson_iter_next(&child5_iter))
{
const char *child5_key =
bson_iter_key(&child5_iter);
flow_t *flow = NULL;
2019-04-27 14:54:30 +00:00
ogs_assert(child5_key);
2017-08-24 08:05:10 +00:00
flow_index = atoi(child5_key);
2019-04-27 14:54:30 +00:00
ogs_assert(
flow_index < MAX_NUM_OF_FLOW);
2017-08-24 08:05:10 +00:00
flow = &pcc_rule->flow[flow_index];
bson_iter_recurse(
&child5_iter, &child6_iter);
while(bson_iter_next(&child6_iter))
{
const char *child6_key =
bson_iter_key(&child6_iter);
if (!strcmp(child6_key, "direction") &&
BSON_ITER_HOLDS_INT32(
&child6_iter))
{
flow->direction =
bson_iter_int32(
&child6_iter);
}
else if (!strcmp(child6_key,
"description") &&
BSON_ITER_HOLDS_UTF8(
&child6_iter))
{
utf8 = bson_iter_utf8(
&child6_iter, &length);
2017-08-25 10:40:49 +00:00
flow->description =
2019-04-27 14:54:30 +00:00
ogs_malloc(length+1);
ogs_cpystrn(
2017-08-25 10:40:49 +00:00
(char*)flow->description,
utf8, length+1);
2017-08-24 08:05:10 +00:00
}
}
flow_index++;
}
pcc_rule->num_of_flow = flow_index;
}
}
2018-01-14 09:15:38 +00:00
/* Charing-Rule-Name is automatically configured */
2018-01-15 02:54:22 +00:00
if (pcc_rule->name)
{
2019-04-27 14:54:30 +00:00
ogs_error("PCC Rule Name has already "
2018-01-15 02:54:22 +00:00
"been defined");
2019-04-27 14:54:30 +00:00
ogs_free(pcc_rule->name);
2018-01-15 02:54:22 +00:00
}
2019-04-27 14:54:30 +00:00
pcc_rule->name = ogs_calloc(
2018-01-15 02:54:22 +00:00
1, MAX_PCC_RULE_NAME_LEN);
2019-04-27 14:54:30 +00:00
ogs_assert(pcc_rule->name);
2018-01-15 02:54:22 +00:00
snprintf(pcc_rule->name, MAX_PCC_RULE_NAME_LEN,
2018-01-14 09:15:38 +00:00
"%s%d", apn, pcc_rule_index+1);
pcc_rule->precedence = pcc_rule_index+1;
pcc_rule->flow_status = FLOW_STATUS_ENABLED;
2017-08-24 08:05:10 +00:00
pcc_rule_index++;
}
2018-01-10 13:09:08 +00:00
gx_message->num_of_pcc_rule = pcc_rule_index;
2017-08-24 08:05:10 +00:00
}
}
}
}
}
out:
if (query) bson_destroy(query);
2017-08-25 10:40:49 +00:00
if (opts) bson_destroy(opts);
2017-08-24 08:05:10 +00:00
if (cursor) mongoc_cursor_destroy(cursor);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_unlock(&self.db_lock);
2017-08-24 08:05:10 +00:00
return rv;
}
2019-04-27 14:54:30 +00:00
int pcrf_sess_set_ipv4(const void *key, uint8_t *sid)
{
2019-04-27 14:54:30 +00:00
ogs_assert(self.ip_hash);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_lock(&self.hash_lock);
2019-04-27 14:54:30 +00:00
ogs_hash_set(self.ip_hash, key, IPV4_LEN, sid);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_unlock(&self.hash_lock);
2019-04-27 14:54:30 +00:00
return OGS_OK;
}
2019-04-27 14:54:30 +00:00
int pcrf_sess_set_ipv6(const void *key, uint8_t *sid)
{
2019-04-27 14:54:30 +00:00
ogs_assert(self.ip_hash);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_lock(&self.hash_lock);
2019-04-27 14:54:30 +00:00
ogs_hash_set(self.ip_hash, key, IPV6_LEN, sid);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_unlock(&self.hash_lock);
2019-04-27 14:54:30 +00:00
return OGS_OK;
}
2019-04-27 14:54:30 +00:00
uint8_t *pcrf_sess_find_by_ipv4(const void *key)
{
2019-04-27 14:54:30 +00:00
uint8_t *sid = NULL;
ogs_assert(key);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_lock(&self.hash_lock);
2019-04-27 14:54:30 +00:00
sid = (uint8_t *)ogs_hash_get(self.ip_hash, key, IPV4_LEN);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_unlock(&self.hash_lock);
return sid;
}
2019-04-27 14:54:30 +00:00
uint8_t *pcrf_sess_find_by_ipv6(const void *key)
{
2019-04-27 14:54:30 +00:00
uint8_t *sid = NULL;
ogs_assert(key);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_lock(&self.hash_lock);
2019-04-27 14:54:30 +00:00
sid = (uint8_t *)ogs_hash_get(self.ip_hash, key, IPV6_LEN);
2019-04-27 14:54:30 +00:00
ogs_thread_mutex_unlock(&self.hash_lock);
return sid;
}
2018-01-09 13:53:09 +00:00