diff --git a/lib/base/types.h b/lib/base/types.h index 37c565121a..b44576de45 100644 --- a/lib/base/types.h +++ b/lib/base/types.h @@ -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 { diff --git a/lib/fd/gx/dict_init.c b/lib/fd/gx/dict_init.c index d57244f650..1da788d2d2 100644 --- a/lib/fd/gx/dict_init.c +++ b/lib/fd/gx/dict_init.c @@ -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) ); diff --git a/lib/fd/gx/gx_lib.h b/lib/fd/gx/gx_dict.h similarity index 98% rename from lib/fd/gx/gx_lib.h rename to lib/fd/gx/gx_dict.h index a9d4eb4c5d..6b37c22439 100644 --- a/lib/fd/gx/gx_lib.h +++ b/lib/fd/gx/gx_dict.h @@ -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__ */ diff --git a/lib/fd/gx/gx_message.h b/lib/fd/gx/gx_message.h new file mode 100644 index 0000000000..b31a325176 --- /dev/null +++ b/lib/fd/gx/gx_message.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__ */ diff --git a/src/hss/hss_context.c b/src/hss/hss_context.c index c70b15f13e..a02d9329ce 100644 --- a/src/hss/hss_context.c +++ b/src/hss/hss_context.c @@ -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; } } diff --git a/src/pcrf/pcrf_context.c b/src/pcrf/pcrf_context.c index 661773e5bf..d2dfe203a4 100644 --- a/src/pcrf/pcrf_context.c +++ b/src/pcrf/pcrf_context.c @@ -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; +} diff --git a/src/pcrf/pcrf_context.h b/src/pcrf/pcrf_context.h index f874b76516..b00a105800 100644 --- a/src/pcrf/pcrf_context.h +++ b/src/pcrf/pcrf_context.h @@ -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 */ diff --git a/src/pcrf/pcrf_fd_path.c b/src/pcrf/pcrf_fd_path.c index 3bfc924cd4..3b4de53973 100644 --- a/src/pcrf/pcrf_fd_path.c +++ b/src/pcrf/pcrf_fd_path.c @@ -3,7 +3,7 @@ #include "core_debug.h" #include "fd_lib.h" -#include "gx_lib.h" +#include "gx_dict.h" #include "pcrf_context.h" diff --git a/src/pgw/pgw_fd_path.c b/src/pgw/pgw_fd_path.c index 282cd3dfa5..aaaa3f5c8a 100644 --- a/src/pgw/pgw_fd_path.c +++ b/src/pgw/pgw_fd_path.c @@ -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" diff --git a/src/pgw/pgw_sm.c b/src/pgw/pgw_sm.c index b9f2e67563..5469c4d1a5 100644 --- a/src/pgw/pgw_sm.c +++ b/src/pgw/pgw_sm.c @@ -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"