PCRF DB interface done
This commit is contained in:
parent
bca462ea85
commit
995a2d2320
|
@ -13,7 +13,6 @@ extern "C" {
|
|||
|
||||
#define MAX_NUM_OF_PDN 8
|
||||
#define MAX_NUM_OF_BEARER 8
|
||||
#define MAX_NUM_OF_UE_PDN (MAX_NUM_OF_UE * MAX_NUM_OF_PDN)
|
||||
#define MAX_NUM_OF_UE_BEARER (MAX_NUM_OF_UE * MAX_NUM_OF_BEARER)
|
||||
|
||||
#define IPV6_LEN 16
|
||||
|
@ -141,6 +140,25 @@ typedef struct _qos_t {
|
|||
bitrate_t gbr; /* Guaranteed Bit Rate (GBR) */
|
||||
} qos_t;
|
||||
|
||||
/**********************************
|
||||
* Flow Structure */
|
||||
typedef struct _flow_t {
|
||||
c_uint8_t direction;
|
||||
#define MAX_FLOW_DESCRIPTION_LEN 255
|
||||
c_uint8_t description[MAX_FLOW_DESCRIPTION_LEN+1];
|
||||
} flow_t;
|
||||
|
||||
/**********************************
|
||||
* PCC Rule Structure */
|
||||
#define MAX_NUM_OF_PCC_RULE 16
|
||||
typedef struct _pcc_rule_t {
|
||||
#define MAX_NUM_OF_FLOW 16
|
||||
flow_t flow[MAX_NUM_OF_FLOW];
|
||||
int num_of_flow;
|
||||
|
||||
qos_t qos;
|
||||
} pcc_rule_t;
|
||||
|
||||
/**********************************
|
||||
* PDN Structure */
|
||||
typedef struct _pdn_t {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "gx_lib.h"
|
||||
#include "gx_dict.h"
|
||||
|
||||
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
|
||||
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef __GX_LIB_H__
|
||||
#define __GX_LIB_H__
|
||||
#ifndef __GX_DICT_H__
|
||||
#define __GX_DICT_H__
|
||||
|
||||
#include "freeDiameter/freeDiameter-host.h"
|
||||
#include "freeDiameter/libfdcore.h"
|
||||
|
@ -91,4 +91,4 @@ int gx_dict_init(void);
|
|||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* ! __GX_LIB_H__ */
|
||||
#endif /* __GX_DICT_H__ */
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __GX_MESSAGE_H__
|
||||
#define __GX_MESSAGE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct _gx_pdn_data_t {
|
||||
pdn_t pdn;
|
||||
pcc_rule_t pcc_rule[MAX_NUM_OF_PCC_RULE];
|
||||
int num_of_pcc_rule;
|
||||
} gx_pdn_data_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __GX_MESSAGE_H__ */
|
|
@ -218,7 +218,7 @@ status_t hss_db_init()
|
|||
context_self()->db_name, "subscribers");
|
||||
d_assert(self.subscriberCollection, return CORE_ERROR,
|
||||
"Couldn't find Subscriber Collection in '%s'",
|
||||
context_self()->db_name)
|
||||
context_self()->db_name);
|
||||
}
|
||||
|
||||
return CORE_OK;
|
||||
|
@ -264,6 +264,7 @@ status_t hss_db_auth_info(
|
|||
rv = CORE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mongoc_cursor_error(cursor, &error))
|
||||
{
|
||||
d_error("Cursor Failure: %s", error.message);
|
||||
|
@ -427,7 +428,14 @@ status_t hss_db_subscription_data(
|
|||
cursor = mongoc_collection_find_with_opts(
|
||||
self.subscriberCollection, query, NULL, NULL);
|
||||
|
||||
mongoc_cursor_next(cursor, &document);
|
||||
if (!mongoc_cursor_next(cursor, &document))
|
||||
{
|
||||
d_error("Cannot find IMSI in DB : %s", imsi_bcd);
|
||||
|
||||
rv = CORE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mongoc_cursor_error(cursor, &error))
|
||||
{
|
||||
d_error("Cursor Failure: %s", error.message);
|
||||
|
@ -596,11 +604,10 @@ status_t hss_db_subscription_data(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
pdn_index++;
|
||||
}
|
||||
|
||||
subscription_data->num_of_pdn = pdn_index + 1;
|
||||
subscription_data->num_of_pdn = pdn_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -213,12 +213,14 @@ status_t pcrf_db_init()
|
|||
{
|
||||
if (context_self()->db_client && context_self()->db_name)
|
||||
{
|
||||
gx_pdn_data_t pdn_data;
|
||||
self.subscriberCollection = mongoc_client_get_collection(
|
||||
context_self()->db_client,
|
||||
context_self()->db_name, "subscribers");
|
||||
d_assert(self.subscriberCollection, return CORE_ERROR,
|
||||
"Couldn't find Subscriber Collection in '%s'",
|
||||
context_self()->db_name)
|
||||
context_self()->db_name);
|
||||
pcrf_db_pdn_data("123", "internet", &pdn_data);
|
||||
}
|
||||
|
||||
return CORE_OK;
|
||||
|
@ -233,3 +235,382 @@ status_t pcrf_db_final()
|
|||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t pcrf_db_pdn_data(
|
||||
c_int8_t *imsi_bcd, c_int8_t *apn, gx_pdn_data_t *pdn_data)
|
||||
{
|
||||
status_t rv = CORE_OK;
|
||||
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;
|
||||
c_uint32_t length = 0;
|
||||
|
||||
d_assert(imsi_bcd, return CORE_ERROR, "Null param");
|
||||
d_assert(apn, return CORE_ERROR, "Null param");
|
||||
d_assert(pdn_data, return CORE_ERROR, "Null param");
|
||||
|
||||
mutex_lock(self.db_lock);
|
||||
|
||||
query = BCON_NEW(
|
||||
"imsi", BCON_UTF8(imsi_bcd),
|
||||
"pdn.apn", BCON_UTF8(apn));
|
||||
opts = BCON_NEW(
|
||||
"projection", "{",
|
||||
"imsi", BCON_INT64(1),
|
||||
"pdn.$", BCON_INT64(1),
|
||||
"}"
|
||||
);
|
||||
cursor = mongoc_collection_find_with_opts(
|
||||
self.subscriberCollection, query, opts, NULL);
|
||||
|
||||
if (!mongoc_cursor_next(cursor, &document))
|
||||
{
|
||||
d_error("Cannot find IMSI(%s)+APN(%s) in DB", imsi_bcd, apn);
|
||||
|
||||
rv = CORE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mongoc_cursor_error(cursor, &error))
|
||||
{
|
||||
d_error("Cursor Failure: %s", error.message);
|
||||
|
||||
rv = CORE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!bson_iter_init(&iter, document))
|
||||
{
|
||||
d_error("bson_iter_init failed in this document");
|
||||
|
||||
rv = CORE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(pdn_data, 0, sizeof(gx_pdn_data_t));
|
||||
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;
|
||||
|
||||
d_assert(child1_key, goto out, "PDN is not ARRAY");
|
||||
pdn_index = atoi(child1_key);
|
||||
d_assert(pdn_index == 0, goto out,
|
||||
"Invalid PDN Index(%d)", pdn_index);
|
||||
|
||||
pdn = &pdn_data->pdn;
|
||||
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);
|
||||
core_cpystrn(pdn->apn, utf8,
|
||||
c_min(length, MAX_APN_LEN)+1);
|
||||
}
|
||||
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_INT32(&child3_iter))
|
||||
{
|
||||
pdn->ambr.uplink =
|
||||
bson_iter_int32(&child3_iter) * 1024;
|
||||
}
|
||||
else if (!strcmp(child3_key, "downlink") &&
|
||||
BSON_ITER_HOLDS_INT32(&child3_iter))
|
||||
{
|
||||
pdn->ambr.downlink =
|
||||
bson_iter_int32(&child3_iter) * 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
d_assert(child3_key, goto out,
|
||||
"PCC RULE is not ARRAY");
|
||||
pcc_rule_index = atoi(child3_key);
|
||||
d_assert(pcc_rule_index < MAX_NUM_OF_PCC_RULE,
|
||||
goto out,
|
||||
"Overflow of PCC RULE number(%d>%d)",
|
||||
pcc_rule_index, MAX_NUM_OF_PCC_RULE);
|
||||
|
||||
pcc_rule = &pdn_data->pcc_rule[pcc_rule_index];
|
||||
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_INT32(
|
||||
&child6_iter))
|
||||
{
|
||||
pcc_rule->qos.mbr.downlink =
|
||||
bson_iter_int32(
|
||||
&child6_iter);
|
||||
}
|
||||
else if (!strcmp(child6_key,
|
||||
"uplink") &&
|
||||
BSON_ITER_HOLDS_INT32(
|
||||
&child6_iter))
|
||||
{
|
||||
pcc_rule->qos.mbr.uplink =
|
||||
bson_iter_int32(
|
||||
&child6_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
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_INT32(
|
||||
&child6_iter))
|
||||
{
|
||||
pcc_rule->qos.gbr.downlink =
|
||||
bson_iter_int32(
|
||||
&child6_iter);
|
||||
}
|
||||
else if (!strcmp(child6_key,
|
||||
"uplink") &&
|
||||
BSON_ITER_HOLDS_INT32(
|
||||
&child6_iter))
|
||||
{
|
||||
pcc_rule->qos.gbr.uplink =
|
||||
bson_iter_int32(
|
||||
&child6_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
d_assert(child5_key, goto out,
|
||||
"FLOW is not ARRAY");
|
||||
flow_index = atoi(child5_key);
|
||||
d_assert(flow_index < MAX_NUM_OF_FLOW,
|
||||
goto out,
|
||||
"Overflow of FLOW number(%d>%d)",
|
||||
flow_index, MAX_NUM_OF_FLOW);
|
||||
|
||||
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);
|
||||
core_cpystrn(
|
||||
(char*)flow->description,
|
||||
utf8,
|
||||
c_min(length,
|
||||
MAX_FLOW_DESCRIPTION_LEN)+1);
|
||||
}
|
||||
}
|
||||
flow_index++;
|
||||
}
|
||||
pcc_rule->num_of_flow = flow_index;
|
||||
}
|
||||
}
|
||||
pcc_rule_index++;
|
||||
}
|
||||
pdn_data->num_of_pcc_rule = pcc_rule_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (query) bson_destroy(query);
|
||||
if (cursor) mongoc_cursor_destroy(cursor);
|
||||
|
||||
mutex_unlock(self.db_lock);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include "core_errno.h"
|
||||
#include "core_mutex.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "gx_message.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -26,6 +28,9 @@ CORE_DECLARE(status_t) pcrf_context_setup_trace_module(void);
|
|||
CORE_DECLARE(status_t) pcrf_db_init(void);
|
||||
CORE_DECLARE(status_t) pcrf_db_final(void);
|
||||
|
||||
CORE_DECLARE(status_t) pcrf_db_pdn_data(
|
||||
c_int8_t *imsi_bcd, c_int8_t *apn, gx_pdn_data_t *pdn_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "core_debug.h"
|
||||
|
||||
#include "fd_lib.h"
|
||||
#include "gx_lib.h"
|
||||
#include "gx_dict.h"
|
||||
|
||||
#include "pcrf_context.h"
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "core_pool.h"
|
||||
|
||||
#include "fd_lib.h"
|
||||
#include "gx_lib.h"
|
||||
#include "gx_dict.h"
|
||||
|
||||
#include "pgw_event.h"
|
||||
#include "pgw_fd_path.h"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "core_lib.h"
|
||||
|
||||
#include "fd_lib.h"
|
||||
#include "gx_lib.h"
|
||||
#include "gx_dict.h"
|
||||
|
||||
#include "pgw_sm.h"
|
||||
#include "pgw_context.h"
|
||||
|
|
Loading…
Reference in New Issue