forked from acouzens/open5gs
refine code
This commit is contained in:
parent
d1303a60e4
commit
4b0565c2e9
|
@ -210,10 +210,16 @@ typedef struct _flow_t {
|
|||
/**********************************
|
||||
* PCC Rule Structure */
|
||||
typedef struct _pcc_rule_t {
|
||||
#define PCC_RULE_TYPE_INSTALL 1
|
||||
#define PCC_RULE_TYPE_REMOVE 2
|
||||
c_uint8_t type;
|
||||
|
||||
#define MAX_PCC_RULE_NAME_LEN 256
|
||||
c_int8_t *name;
|
||||
|
||||
flow_t flow[MAX_NUM_OF_FLOW];
|
||||
int num_of_flow;
|
||||
|
||||
#define GX_FLOW_STATUS_ENABLED_UPLINK 0
|
||||
#define GX_FLOW_STATUS_ENABLED_DOWNLINK 1
|
||||
#define GX_FLOW_STATUS_ENABLED 2
|
||||
|
|
|
@ -10,6 +10,13 @@ extern "C" {
|
|||
|
||||
#define GX_APPLICATION_ID 16777238
|
||||
|
||||
#define GX_AVP_CODE_RE_AUTH_REQUEST_TYPE (285)
|
||||
#define GX_AVP_CODE_CC_REQUEST_NUMBER (415)
|
||||
#define GX_AVP_CODE_CC_REQUEST_TYPE (416)
|
||||
#define GX_AVP_CODE_DEFAULT_EPS_BEARER_QOS (1049)
|
||||
#define GX_AVP_CODE_SUPPORTED_FEATURES (628)
|
||||
#define GX_AVP_CODE_CHARGING_RULE_INSTALL (1001)
|
||||
#define GX_AVP_CODE_CHARGING_RULE_REMOVE (1002)
|
||||
#define GX_AVP_CODE_CHARGING_RULE_DEFINITION (1003)
|
||||
#define GX_AVP_CODE_CHARGING_RULE_NAME (1005)
|
||||
#define GX_AVP_CODE_FLOW_INFORMATION (1058)
|
||||
|
|
|
@ -1244,6 +1244,25 @@ pgw_bearer_t* pgw_bearer_find_by_ebi(pgw_sess_t *sess, c_uint8_t ebi)
|
|||
return bearer;
|
||||
}
|
||||
|
||||
pgw_bearer_t* pgw_bearer_find_by_name(pgw_sess_t *sess, c_int8_t *name)
|
||||
{
|
||||
pgw_bearer_t *bearer = NULL;
|
||||
|
||||
d_assert(sess, return NULL, "Null param");
|
||||
d_assert(name, return NULL, "Null param");
|
||||
|
||||
bearer = pgw_bearer_first(sess);
|
||||
while (bearer)
|
||||
{
|
||||
if (bearer->name && strcmp(bearer->name, name) == 0)
|
||||
return bearer;
|
||||
|
||||
bearer = pgw_bearer_next(bearer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pgw_bearer_t* pgw_bearer_find_by_qci_arp(pgw_sess_t *sess,
|
||||
c_uint8_t qci,
|
||||
c_uint8_t priority_level,
|
||||
|
|
|
@ -232,6 +232,8 @@ CORE_DECLARE(pgw_bearer_t*) pgw_bearer_find_by_pgw_s5u_teid(
|
|||
c_uint32_t pgw_s5u_teid);
|
||||
CORE_DECLARE(pgw_bearer_t*) pgw_bearer_find_by_ebi(
|
||||
pgw_sess_t *sess, c_uint8_t ebi);
|
||||
CORE_DECLARE(pgw_bearer_t*) pgw_bearer_find_by_name(
|
||||
pgw_sess_t *sess, c_int8_t *name);
|
||||
CORE_DECLARE(pgw_bearer_t*) pgw_bearer_find_by_qci_arp(pgw_sess_t *sess,
|
||||
c_uint8_t qci,
|
||||
c_uint8_t priority_level,
|
||||
|
|
|
@ -554,39 +554,6 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
error++;
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, gx_charging_rule_install, &avp);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avp)
|
||||
{
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
d_assert(ret == 0, return,);
|
||||
while(avpch1)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
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];
|
||||
|
||||
rv = decode_pcc_rule_definition(pcc_rule, avpch1, &error);
|
||||
d_assert(rv == CORE_OK, return,);
|
||||
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ret = fd_msg_search_avp(*msg, gx_qos_information, &avp);
|
||||
d_assert(ret == 0, return,);
|
||||
if (avp)
|
||||
|
@ -658,6 +625,72 @@ static void pgw_gx_cca_cb(void *data, struct msg **msg)
|
|||
}
|
||||
}
|
||||
|
||||
ret = fd_msg_browse(*msg, MSG_BRW_FIRST_CHILD, &avp, NULL);
|
||||
d_assert(ret == 0, return,);
|
||||
while(avp)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
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);
|
||||
d_assert(ret == 0, return,);
|
||||
while(avpch1)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
d_assert(ret == 0, return,);
|
||||
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];
|
||||
|
||||
rv = decode_pcc_rule_definition(
|
||||
pcc_rule, avpch1, &error);
|
||||
d_assert(rv == CORE_OK, return,);
|
||||
|
||||
pcc_rule->type = PCC_RULE_TYPE_INSTALL;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!error)
|
||||
{
|
||||
|
@ -796,37 +829,65 @@ static int pgw_gx_rar_cb( struct msg **msg, struct avp *avp,
|
|||
sess = sess_data->sess;
|
||||
d_assert(sess, return EINVAL,);
|
||||
|
||||
ret = fd_msg_search_avp(qry, gx_charging_rule_install, &avp);
|
||||
ret = fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
if (avp)
|
||||
while(avp)
|
||||
{
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
ret = fd_msg_avp_hdr(avp, &hdr);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
while(avpch1)
|
||||
switch(hdr->avp_code)
|
||||
{
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
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 GX_AVP_CODE_CHARGING_RULE_DEFINITION:
|
||||
ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
while(avpch1)
|
||||
{
|
||||
pcc_rule_t *pcc_rule =
|
||||
&gx_message->pcc_rule[gx_message->num_of_pcc_rule];
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
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];
|
||||
|
||||
rv = decode_pcc_rule_definition(pcc_rule, avpch1, NULL);
|
||||
d_assert(rv == CORE_OK, return EINVAL,);
|
||||
rv = decode_pcc_rule_definition(
|
||||
pcc_rule, avpch1, NULL);
|
||||
d_assert(rv == CORE_OK, return EINVAL,);
|
||||
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
pcc_rule->type = PCC_RULE_TYPE_INSTALL;
|
||||
gx_message->num_of_pcc_rule++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_warn("Not supported(%d)", hdr->avp_code);
|
||||
break;
|
||||
}
|
||||
fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL);
|
||||
}
|
||||
fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL);
|
||||
}
|
||||
|
||||
/* Send Gx Event to PGW State Machine */
|
||||
|
|
|
@ -99,59 +99,97 @@ static status_t bearer_binding(pgw_sess_t *sess, gx_message_t *gx_message)
|
|||
gtp_xact_t *xact = NULL;
|
||||
gtp_header_t h;
|
||||
pkbuf_t *pkbuf = NULL;
|
||||
pgw_bearer_t *bearer = NULL;
|
||||
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule[i];
|
||||
pgw_bearer_t *bearer = pgw_bearer_find_by_qci_arp(sess,
|
||||
pcc_rule->qos.qci,
|
||||
pcc_rule->qos.arp.priority_level,
|
||||
pcc_rule->qos.arp.pre_emption_capability,
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability);
|
||||
if (bearer)
|
||||
|
||||
d_assert(pcc_rule, return CORE_ERROR,);
|
||||
if (pcc_rule->name == NULL)
|
||||
{
|
||||
d_error("CHECK WEBUI : PCC Rule Modification is NOT implemented");
|
||||
d_error("Please remove Flow in PCC Rule");
|
||||
d_error("No PCC Rule Name");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcc_rule->type == PCC_RULE_TYPE_INSTALL)
|
||||
{
|
||||
bearer = pgw_bearer_find_by_qci_arp(sess,
|
||||
pcc_rule->qos.qci,
|
||||
pcc_rule->qos.arp.priority_level,
|
||||
pcc_rule->qos.arp.pre_emption_capability,
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability);
|
||||
if (bearer)
|
||||
{
|
||||
d_error("CHECK WEBUI : "
|
||||
"PCC Rule Modification is NOT implemented");
|
||||
d_error("Please remove Flow in PCC Rule "
|
||||
"[QCI:%d, ARP:%d,%d,%d]",
|
||||
pcc_rule->qos.qci,
|
||||
pcc_rule->qos.arp.priority_level,
|
||||
pcc_rule->qos.arp.pre_emption_capability,
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability);
|
||||
|
||||
return CORE_ERROR;
|
||||
}
|
||||
|
||||
bearer = pgw_bearer_find_by_name(sess, pcc_rule->name);
|
||||
if (bearer)
|
||||
{
|
||||
d_error("CHECK WEBUI : "
|
||||
"PCC Rule Modification is NOT implemented");
|
||||
d_error("Please remove Flow in PCC Rule [Name:%d]",
|
||||
pcc_rule->name);
|
||||
|
||||
return CORE_ERROR;
|
||||
}
|
||||
|
||||
bearer = pgw_bearer_add(sess);
|
||||
d_assert(bearer, return CORE_ERROR, "Null param");
|
||||
|
||||
bearer->name = core_strdup(pcc_rule->name);
|
||||
d_assert(bearer->name, return CORE_ERROR,);
|
||||
|
||||
memcpy(&bearer->qos, &pcc_rule->qos, sizeof(qos_t));
|
||||
|
||||
for (j = 0; j < pcc_rule->num_of_flow; j++)
|
||||
{
|
||||
flow_t *flow = &pcc_rule->flow[j];
|
||||
pgw_rule_t rule;
|
||||
pgw_pf_t *pf = NULL;
|
||||
|
||||
d_assert(flow, return CORE_ERROR, "Null param");
|
||||
d_assert(flow->description, return CORE_ERROR, "Null param");
|
||||
|
||||
rv = pgw_compile_packet_filter(&rule, flow->description);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR,
|
||||
"Failed to compile packet filter");
|
||||
|
||||
pf = pgw_pf_add(bearer, pcc_rule->precedence);
|
||||
d_assert(pf, return CORE_ERROR, "Null param");
|
||||
|
||||
memcpy(&pf->rule, &rule, sizeof(pgw_rule_t));
|
||||
pf->direction = flow->direction;
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof(gtp_header_t));
|
||||
h.type = GTP_CREATE_BEARER_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
rv = pgw_s5c_build_create_bearer_request(&pkbuf, h.type, bearer);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
||||
|
||||
xact = gtp_xact_local_create(sess->gnode, &h, pkbuf);
|
||||
d_assert(xact, return CORE_ERROR, "Null param");
|
||||
|
||||
rv = gtp_xact_commit(xact);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
||||
}
|
||||
else if (pcc_rule->type == PCC_RULE_TYPE_REMOVE)
|
||||
{
|
||||
d_warn("Not implmeneted");
|
||||
return CORE_ERROR;
|
||||
}
|
||||
|
||||
bearer = pgw_bearer_add(sess);
|
||||
d_assert(bearer, return CORE_ERROR, "Null param");
|
||||
|
||||
bearer->name = core_strdup(pcc_rule->name);
|
||||
d_assert(bearer->name, return CORE_ERROR,);
|
||||
|
||||
memcpy(&bearer->qos, &pcc_rule->qos, sizeof(qos_t));
|
||||
|
||||
for (j = 0; j < pcc_rule->num_of_flow; j++)
|
||||
{
|
||||
flow_t *flow = &pcc_rule->flow[j];
|
||||
pgw_rule_t rule;
|
||||
pgw_pf_t *pf = NULL;
|
||||
|
||||
d_assert(flow, return CORE_ERROR, "Null param");
|
||||
d_assert(flow->description, return CORE_ERROR, "Null param");
|
||||
|
||||
rv = pgw_compile_packet_filter(&rule, flow->description);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR, "Failed to compile packet filter");
|
||||
|
||||
pf = pgw_pf_add(bearer, pcc_rule->precedence);
|
||||
d_assert(pf, return CORE_ERROR, "Null param");
|
||||
|
||||
memcpy(&pf->rule, &rule, sizeof(pgw_rule_t));
|
||||
pf->direction = flow->direction;
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof(gtp_header_t));
|
||||
h.type = GTP_CREATE_BEARER_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
rv = pgw_s5c_build_create_bearer_request(&pkbuf, h.type, bearer);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR, "S11 build error");
|
||||
|
||||
xact = gtp_xact_local_create(sess->gnode, &h, pkbuf);
|
||||
d_assert(xact, return CORE_ERROR, "Null param");
|
||||
|
||||
rv = gtp_xact_commit(xact);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR, "xact_commit error");
|
||||
else
|
||||
d_assert(0, return CORE_ERROR, "Invalid type(%d)", pcc_rule->type);
|
||||
}
|
||||
|
||||
return CORE_OK;
|
||||
|
|
Loading…
Reference in New Issue