re-factoring Gx/Rx diameter to apply modification
This commit is contained in:
parent
4acc21093b
commit
f1e41050c3
|
@ -220,10 +220,11 @@ typedef struct _pcc_rule_t {
|
|||
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
|
||||
#define GX_FLOW_STATUS_DISABLED 3
|
||||
#define FLOW_STATUS_ENABLED_UPLINK 0
|
||||
#define FLOW_STATUS_ENABLED_DOWNLINK 1
|
||||
#define FLOW_STATUS_ENABLED 2
|
||||
#define FLOW_STATUS_DISABLED 3
|
||||
#define FLOW_STATUS_REMOVE 4
|
||||
c_int8_t flow_status;
|
||||
c_uint32_t precedence;
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ extern "C" {
|
|||
#define RX_AVP_CODE_MEDIA_TYPE (520)
|
||||
#define RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_DL (515)
|
||||
#define RX_AVP_CODE_MAX_REQUESTED_BANDWIDTH_UL (516)
|
||||
#define RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_DL (534)
|
||||
#define RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_UL (535)
|
||||
#define RX_AVP_CODE_MEDIA_COMPONENT_NUMBER (518)
|
||||
|
||||
#define RX_AVP_CODE_MEDIA_SUB_COMPONENT (519)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
void rx_message_free(rx_message_t *rx_message)
|
||||
{
|
||||
int i, j;
|
||||
int i, j, k;
|
||||
|
||||
d_assert(rx_message, return, "Null param");
|
||||
|
||||
|
@ -16,16 +16,21 @@ void rx_message_free(rx_message_t *rx_message)
|
|||
rx_media_component_t *media_component =
|
||||
&rx_message->media_component[i];
|
||||
|
||||
for (j = 0; j < media_component->num_of_flow; j++)
|
||||
for (j = 0; j < media_component->num_of_sub; j++)
|
||||
{
|
||||
flow_t *flow = &media_component->flow[j];
|
||||
rx_media_sub_component_t *sub = &media_component->sub[j];
|
||||
|
||||
if (flow->description)
|
||||
for (k = 0; k < sub->num_of_flow; k++)
|
||||
{
|
||||
CORE_FREE(flow->description);
|
||||
flow_t *flow = &sub->flow[k];
|
||||
|
||||
if (flow->description)
|
||||
{
|
||||
CORE_FREE(flow->description);
|
||||
}
|
||||
else
|
||||
d_assert(0,, "Null param");
|
||||
}
|
||||
else
|
||||
d_assert(0,, "Null param");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,18 @@ extern "C" {
|
|||
|
||||
#include "3gpp_types.h"
|
||||
|
||||
typedef struct _rx_media_sub_component_t {
|
||||
c_uint32_t flow_number;
|
||||
#define RX_FLOW_USAGE_NO_INFORMATION 0
|
||||
#define RX_FLOW_USAGE_RTCP 1
|
||||
#define RX_FLOW_USAGE_AF_SIGNALLING 2
|
||||
c_uint32_t flow_usage;
|
||||
flow_t flow[MAX_NUM_OF_FLOW];
|
||||
int num_of_flow;
|
||||
} rx_media_sub_component_t;
|
||||
|
||||
typedef struct _rx_media_component_t {
|
||||
c_uint32_t media_component_number;
|
||||
#define RX_MEDIA_TYPE_AUDIO 0
|
||||
#define RX_MEDIA_TYPE_VIDEO 1
|
||||
#define RX_MEDIA_TYPE_DATA 2
|
||||
|
@ -21,12 +32,9 @@ typedef struct _rx_media_component_t {
|
|||
bitrate_t mbr; /* Maxmimum Bit Rate (MBR) */
|
||||
bitrate_t gbr; /* Guaranteed Bit Rate (GBR) */
|
||||
|
||||
#define RX_FLOW_USAGE_NO_INFORMATION 0
|
||||
#define RX_FLOW_USAGE_RTCP 1
|
||||
#define RX_FLOW_USAGE_AF_SIGNALLING 2
|
||||
c_uint32_t flow_usage;
|
||||
flow_t flow[MAX_NUM_OF_FLOW];
|
||||
int num_of_flow;
|
||||
#define MAX_NUM_OF_MEDIA_SUB_COMPONENT 8
|
||||
rx_media_sub_component_t sub[MAX_NUM_OF_MEDIA_SUB_COMPONENT];
|
||||
int num_of_sub;
|
||||
} rx_media_component_t;
|
||||
|
||||
typedef struct _rx_message_t {
|
||||
|
|
|
@ -759,7 +759,7 @@ status_t pcrf_db_qos_data(
|
|||
snprintf(pcc_rule->name, MAX_PCC_RULE_NAME_LEN,
|
||||
"%s%d", apn, pcc_rule_index+1);
|
||||
pcc_rule->precedence = pcc_rule_index+1;
|
||||
pcc_rule->flow_status = GX_FLOW_STATUS_ENABLED;
|
||||
pcc_rule->flow_status = FLOW_STATUS_ENABLED;
|
||||
pcc_rule_index++;
|
||||
}
|
||||
gx_message->num_of_pcc_rule = pcc_rule_index;
|
||||
|
|
|
@ -553,7 +553,7 @@ status_t pcrf_gx_send_rar(
|
|||
c_uint8_t *gx_sid, c_uint8_t *rx_sid, rx_message_t *rx_message)
|
||||
{
|
||||
status_t rv;
|
||||
int ret = 0, i, j;
|
||||
int ret = 0, i, j, k;
|
||||
|
||||
struct msg *req = NULL;
|
||||
struct avp *avp, *avpch1;
|
||||
|
@ -565,6 +565,7 @@ status_t pcrf_gx_send_rar(
|
|||
size_t sidlen;
|
||||
|
||||
gx_message_t gx_message;
|
||||
int charging_rule = 0;
|
||||
|
||||
d_assert(gx_sid, return CORE_ERROR,);
|
||||
d_assert(rx_sid, return CORE_ERROR,);
|
||||
|
@ -632,8 +633,6 @@ status_t pcrf_gx_send_rar(
|
|||
|
||||
if (rx_message->cmd_code == RX_CMD_CODE_AA)
|
||||
{
|
||||
int charging_rule_install = 0;
|
||||
|
||||
if (!rx_sess_data->sid)
|
||||
{
|
||||
rx_sess_data->sid = (os0_t)core_strdup((char *)rx_sid);
|
||||
|
@ -660,6 +659,11 @@ status_t pcrf_gx_send_rar(
|
|||
rx_media_component_t *media_component =
|
||||
&rx_message->media_component[i];
|
||||
|
||||
if (media_component->media_component_number == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(media_component->media_type)
|
||||
{
|
||||
case RX_MEDIA_TYPE_AUDIO:
|
||||
|
@ -687,7 +691,8 @@ status_t pcrf_gx_send_rar(
|
|||
|
||||
if (!pcc_rule)
|
||||
{
|
||||
d_error("No PCC Rule : [QCI:%d]", qci);
|
||||
d_error("CHECK WEBUI : No PCC Rule [QCI:%d]", qci);
|
||||
d_error("Please add PCC Rule using WEBUI");
|
||||
rx_message->result_code =
|
||||
RX_DIAMETER_REQUESTED_SERVICE_NOT_AUTHORIZED;
|
||||
goto out;
|
||||
|
@ -695,58 +700,80 @@ status_t pcrf_gx_send_rar(
|
|||
|
||||
if (pcc_rule->num_of_flow)
|
||||
{
|
||||
d_error("CHECK WEBUI : PCC Rule Modification is NOT implemented");
|
||||
d_error("Please remove Flow in PCC Rule");
|
||||
rx_message->result_code = RX_DIAMETER_FILTER_RESTRICTIONS;
|
||||
goto out;
|
||||
d_warn("STATIC dedicated bearer has already been activated");
|
||||
d_warn("EPC will initiate modify dedicated bearer");
|
||||
|
||||
for (j = 0; j < pcc_rule->num_of_flow; j++)
|
||||
{
|
||||
flow_t *flow = &pcc_rule->flow[j];
|
||||
|
||||
if (flow->description)
|
||||
{
|
||||
CORE_FREE(flow->description);
|
||||
}
|
||||
else
|
||||
d_assert(0,, "Null param");
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow = 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < media_component->num_of_flow; j++)
|
||||
for (j = 0; j < media_component->num_of_sub; j++)
|
||||
{
|
||||
int len;
|
||||
flow_t *rx_flow = &media_component->flow[j];
|
||||
flow_t *gx_flow = &pcc_rule->flow[j];
|
||||
rx_media_sub_component_t *sub = &media_component->sub[j];
|
||||
|
||||
if (!strncmp(rx_flow->description,
|
||||
"permit out", strlen("permit out")))
|
||||
if (sub->flow_number == 0)
|
||||
{
|
||||
gx_flow->direction = FLOW_DOWNLINK_ONLY;
|
||||
|
||||
len = strlen(rx_flow->description)+1;
|
||||
gx_flow->description = core_malloc(len);
|
||||
core_cpystrn(gx_flow->description,
|
||||
rx_flow->description, len);
|
||||
}
|
||||
else if (!strncmp(rx_flow->description,
|
||||
"permit in", strlen("permit in")))
|
||||
{
|
||||
gx_flow->direction = FLOW_UPLINK_ONLY;
|
||||
|
||||
/* 'permit in' should be changed
|
||||
* 'permit out' in Gx Diameter */
|
||||
len = strlen(rx_flow->description)+2;
|
||||
gx_flow->description = core_malloc(len);
|
||||
strcpy(gx_flow->description, "permit out");
|
||||
strcat(gx_flow->description,
|
||||
&rx_flow->description[strlen("permit in")]);
|
||||
d_assert(len == strlen(gx_flow->description)+1, goto out,);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("Invalid Flow Descripton : [%s]",
|
||||
rx_flow->description);
|
||||
rx_message->result_code = RX_DIAMETER_FILTER_RESTRICTIONS;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow++;
|
||||
for (k = 0; k < sub->num_of_flow; k++)
|
||||
{
|
||||
int len;
|
||||
flow_t *gx_flow = &pcc_rule->flow[pcc_rule->num_of_flow];
|
||||
flow_t *rx_flow = &sub->flow[k];
|
||||
|
||||
if (!strncmp(rx_flow->description,
|
||||
"permit out", strlen("permit out")))
|
||||
{
|
||||
gx_flow->direction = FLOW_DOWNLINK_ONLY;
|
||||
|
||||
len = strlen(rx_flow->description)+1;
|
||||
gx_flow->description = core_malloc(len);
|
||||
core_cpystrn(gx_flow->description,
|
||||
rx_flow->description, len);
|
||||
}
|
||||
else if (!strncmp(rx_flow->description,
|
||||
"permit in", strlen("permit in")))
|
||||
{
|
||||
gx_flow->direction = FLOW_UPLINK_ONLY;
|
||||
|
||||
/* 'permit in' should be changed
|
||||
* 'permit out' in Gx Diameter */
|
||||
len = strlen(rx_flow->description)+2;
|
||||
gx_flow->description = core_malloc(len);
|
||||
strcpy(gx_flow->description, "permit out");
|
||||
strcat(gx_flow->description,
|
||||
&rx_flow->description[strlen("permit in")]);
|
||||
d_assert(len == strlen(gx_flow->description)+1, goto out,);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_error("Invalid Flow Descripton : [%s]",
|
||||
rx_flow->description);
|
||||
rx_message->result_code = RX_DIAMETER_FILTER_RESTRICTIONS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pcc_rule->num_of_flow++;
|
||||
}
|
||||
}
|
||||
|
||||
if (charging_rule_install == 0)
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
ret = fd_msg_avp_new(gx_charging_rule_install, 0, &avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
charging_rule_install = 1;
|
||||
charging_rule = 1;
|
||||
}
|
||||
|
||||
rv = encode_pcc_rule_definition(avp, pcc_rule);
|
||||
|
@ -760,7 +787,7 @@ status_t pcrf_gx_send_rar(
|
|||
rx_sess_data->num_of_name++;
|
||||
}
|
||||
|
||||
if (charging_rule_install == 1)
|
||||
if (charging_rule == 1)
|
||||
{
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
@ -769,19 +796,17 @@ status_t pcrf_gx_send_rar(
|
|||
}
|
||||
else if (rx_message->cmd_code == RX_CMD_CODE_SESSION_TERMINATION)
|
||||
{
|
||||
int charging_rule_remove = 0;
|
||||
|
||||
d_assert(rx_sess_data->sid, return CORE_ERROR,);
|
||||
|
||||
for (i = 0; i < rx_sess_data->num_of_name; i++)
|
||||
{
|
||||
d_assert(rx_sess_data->name[i],,);
|
||||
|
||||
if (charging_rule_remove == 0)
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
ret = fd_msg_avp_new(gx_charging_rule_remove, 0, &avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
charging_rule_remove = 1;
|
||||
charging_rule = 1;
|
||||
}
|
||||
|
||||
ret = fd_msg_avp_new(gx_charging_rule_name, 0, &avpch1);
|
||||
|
@ -794,7 +819,7 @@ status_t pcrf_gx_send_rar(
|
|||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
}
|
||||
|
||||
if (charging_rule_remove == 1)
|
||||
if (charging_rule == 1)
|
||||
{
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
@ -804,6 +829,12 @@ status_t pcrf_gx_send_rar(
|
|||
d_assert(0, return CORE_ERROR,
|
||||
"Invalid Command Code(%d)", rx_message->cmd_code);
|
||||
|
||||
if (charging_rule == 0)
|
||||
{
|
||||
rx_message->result_code = ER_DIAMETER_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set Origin-Host & Origin-Realm */
|
||||
ret = fd_msg_add_origin(req, 0);
|
||||
d_assert(ret == 0, return CORE_ERROR,);
|
||||
|
|
|
@ -203,7 +203,11 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
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;
|
||||
|
@ -219,8 +223,21 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
media_component->mbr.uplink = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_DL:
|
||||
{
|
||||
media_component->gbr.downlink = hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_MIN_REQUESTED_BANDWIDTH_UL:
|
||||
{
|
||||
media_component->gbr.uplink = 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];
|
||||
|
||||
ret = fd_msg_browse(avpch2, MSG_BRW_FIRST_CHILD,
|
||||
&avpch3, NULL);
|
||||
d_assert(ret == 0, return EINVAL,);
|
||||
|
@ -231,17 +248,19 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
switch(hdr->avp_code)
|
||||
{
|
||||
case RX_AVP_CODE_FLOW_NUMBER:
|
||||
sub->flow_number =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
case RX_AVP_CODE_FLOW_USAGE:
|
||||
{
|
||||
media_component->flow_usage =
|
||||
sub->flow_usage =
|
||||
hdr->avp_value->i32;
|
||||
break;
|
||||
}
|
||||
case RX_AVP_CODE_FLOW_DESCRIPTION:
|
||||
{
|
||||
flow_t *flow = &media_component->flow
|
||||
[media_component->num_of_flow];
|
||||
flow_t *flow = &sub->flow
|
||||
[sub->num_of_flow];
|
||||
|
||||
flow->description = core_malloc(
|
||||
hdr->avp_value->os.len+1);
|
||||
|
@ -249,7 +268,8 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
flow->description,
|
||||
(char*)hdr->avp_value->os.data,
|
||||
hdr->avp_value->os.len+1);
|
||||
media_component->num_of_flow++;
|
||||
|
||||
sub->num_of_flow++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -262,6 +282,7 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
fd_msg_browse(avpch3, MSG_BRW_NEXT, &avpch3, NULL);
|
||||
}
|
||||
|
||||
media_component->num_of_sub++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -291,8 +312,11 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
|
|||
if (rv != CORE_OK)
|
||||
{
|
||||
result_code = rx_message.result_code;
|
||||
d_error("pcrf_gx_send_rar() failed");
|
||||
goto out;
|
||||
if (result_code != ER_DIAMETER_SUCCESS)
|
||||
{
|
||||
d_error("pcrf_gx_send_rar() failed");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store Gx Session-Id in this session */
|
||||
|
|
|
@ -102,6 +102,7 @@ static status_t bearer_binding(pgw_sess_t *sess, gx_message_t *gx_message)
|
|||
pgw_bearer_t *bearer = NULL;
|
||||
|
||||
pcc_rule_t *pcc_rule = &gx_message->pcc_rule[i];
|
||||
int bearer_created = 0;
|
||||
|
||||
d_assert(pcc_rule, return CORE_ERROR,);
|
||||
if (pcc_rule->name == NULL)
|
||||
|
@ -117,39 +118,38 @@ static status_t bearer_binding(pgw_sess_t *sess, gx_message_t *gx_message)
|
|||
pcc_rule->qos.arp.priority_level,
|
||||
pcc_rule->qos.arp.pre_emption_capability,
|
||||
pcc_rule->qos.arp.pre_emption_vulnerability);
|
||||
if (bearer)
|
||||
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]",
|
||||
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));
|
||||
d_assert(pcc_rule->num_of_flow, return CORE_ERROR,
|
||||
"No Flow! [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_created = 1;
|
||||
}
|
||||
|
||||
bearer = pgw_bearer_find_by_name(sess, pcc_rule->name);
|
||||
if (bearer)
|
||||
else
|
||||
{
|
||||
d_error("CHECK WEBUI : "
|
||||
"PCC Rule Modification is NOT implemented");
|
||||
d_error("Please remove Flow in PCC Rule [Name:%d]",
|
||||
pcc_rule->name);
|
||||
d_assert(strcmp(bearer->name, pcc_rule->name) == 0,
|
||||
return CORE_ERROR,
|
||||
"PCC Rule Name Mismatched! [%s:%s]",
|
||||
bearer->name, pcc_rule->name);
|
||||
|
||||
return CORE_ERROR;
|
||||
if (pcc_rule->num_of_flow)
|
||||
{
|
||||
/* Remove all previous flow */
|
||||
pgw_pf_remove_all(bearer);
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
|
@ -171,11 +171,23 @@ static status_t bearer_binding(pgw_sess_t *sess, gx_message_t *gx_message)
|
|||
}
|
||||
|
||||
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");
|
||||
if (bearer_created == 1)
|
||||
{
|
||||
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");
|
||||
}
|
||||
else
|
||||
{
|
||||
h.type = GTP_UPDATE_BEARER_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
rv = pgw_s5c_build_update_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");
|
||||
|
|
|
@ -348,6 +348,172 @@ status_t pgw_s5c_build_create_bearer_request(
|
|||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t pgw_s5c_build_update_bearer_request(
|
||||
pkbuf_t **pkbuf, c_uint8_t type, pgw_bearer_t *bearer)
|
||||
{
|
||||
status_t rv;
|
||||
pgw_sess_t *sess = NULL;
|
||||
pgw_bearer_t *linked_bearer = NULL;
|
||||
|
||||
gtp_message_t gtp_message;
|
||||
gtp_update_bearer_request_t *req = NULL;
|
||||
|
||||
gtp_bearer_qos_t bearer_qos;
|
||||
char bearer_qos_buf[GTP_BEARER_QOS_LEN];
|
||||
gtp_tft_t tft;
|
||||
int i, j, len;
|
||||
char tft_buf[GTP_MAX_TRAFFIC_FLOW_TEMPLATE];
|
||||
pgw_pf_t *pf = NULL;
|
||||
|
||||
d_assert(bearer, return CORE_ERROR, "Null param");
|
||||
sess = bearer->sess;
|
||||
d_assert(sess, return CORE_ERROR, "Null param");
|
||||
linked_bearer = pgw_default_bearer_in_sess(sess);
|
||||
d_assert(linked_bearer, return CORE_ERROR, "Null param");
|
||||
|
||||
req = >p_message.update_bearer_request;
|
||||
memset(>p_message, 0, sizeof(gtp_message_t));
|
||||
|
||||
/* Bearer EBI */
|
||||
req->bearer_contexts.presence = 1;
|
||||
req->bearer_contexts.eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
/* Bearer QoS */
|
||||
memset(&bearer_qos, 0, sizeof(bearer_qos));
|
||||
bearer_qos.qci = bearer->qos.qci;
|
||||
bearer_qos.priority_level = bearer->qos.arp.priority_level;
|
||||
bearer_qos.pre_emption_capability =
|
||||
bearer->qos.arp.pre_emption_capability;
|
||||
bearer_qos.pre_emption_vulnerability =
|
||||
bearer->qos.arp.pre_emption_vulnerability;
|
||||
bearer_qos.dl_mbr = bearer->qos.mbr.downlink;
|
||||
bearer_qos.ul_mbr = bearer->qos.mbr.uplink;
|
||||
bearer_qos.dl_gbr = bearer->qos.gbr.downlink;
|
||||
bearer_qos.ul_gbr = bearer->qos.gbr.uplink;
|
||||
|
||||
req->bearer_contexts.bearer_level_qos.presence = 1;
|
||||
gtp_build_bearer_qos(&req->bearer_contexts.bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf, GTP_BEARER_QOS_LEN);
|
||||
|
||||
/* Bearer TFT */
|
||||
memset(&tft, 0, sizeof(tft));
|
||||
tft.code = GTP_TFT_CODE_CREATE_NEW_TFT;
|
||||
|
||||
i = 0;
|
||||
pf = pgw_pf_first(bearer);
|
||||
while(pf)
|
||||
{
|
||||
tft.pf[i].direction = pf->direction;
|
||||
tft.pf[i].identifier = pf->identifier - 1;
|
||||
tft.pf[i].precedence = i+1;
|
||||
|
||||
j = 0, len = 0;
|
||||
if (pf->rule.proto)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE;
|
||||
tft.pf[i].component[j].proto = pf->rule.proto;
|
||||
j++; len += 2;
|
||||
}
|
||||
|
||||
if (pf->rule.ipv4_local)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE;
|
||||
tft.pf[i].component[j].ipv4.addr = pf->rule.ip.local.addr[0];
|
||||
tft.pf[i].component[j].ipv4.mask = pf->rule.ip.local.mask[0];
|
||||
j++; len += 9;
|
||||
}
|
||||
|
||||
if (pf->rule.ipv4_remote)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE;
|
||||
tft.pf[i].component[j].ipv4.addr = pf->rule.ip.remote.addr[0];
|
||||
tft.pf[i].component[j].ipv4.mask = pf->rule.ip.remote.mask[0];
|
||||
j++; len += 9;
|
||||
}
|
||||
|
||||
if (pf->rule.ipv6_local)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE;
|
||||
memcpy(tft.pf[i].component[j].ipv6.addr, pf->rule.ip.local.addr,
|
||||
sizeof pf->rule.ip.local.addr);
|
||||
tft.pf[i].component[j].ipv6.prefixlen =
|
||||
contigmask((c_uint8_t *)pf->rule.ip.local.mask, 128);
|
||||
j++; len += 18;
|
||||
}
|
||||
|
||||
if (pf->rule.ipv6_remote)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE;
|
||||
memcpy(tft.pf[i].component[j].ipv6.addr, pf->rule.ip.remote.addr,
|
||||
sizeof pf->rule.ip.remote.addr);
|
||||
tft.pf[i].component[j].ipv6.prefixlen =
|
||||
contigmask((c_uint8_t *)pf->rule.ip.remote.mask, 128);
|
||||
j++; len += 18;
|
||||
}
|
||||
|
||||
if (pf->rule.port.local.low)
|
||||
{
|
||||
if (pf->rule.port.local.low == pf->rule.port.local.high)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE;
|
||||
tft.pf[i].component[j].port.low = pf->rule.port.local.low;
|
||||
j++; len += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE;
|
||||
tft.pf[i].component[j].port.low = pf->rule.port.local.low;
|
||||
tft.pf[i].component[j].port.high = pf->rule.port.local.high;
|
||||
j++; len += 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (pf->rule.port.remote.low)
|
||||
{
|
||||
if (pf->rule.port.remote.low == pf->rule.port.remote.high)
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE;
|
||||
tft.pf[i].component[j].port.low = pf->rule.port.remote.low;
|
||||
j++; len += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
tft.pf[i].component[j].type =
|
||||
GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE;
|
||||
tft.pf[i].component[j].port.low = pf->rule.port.remote.low;
|
||||
tft.pf[i].component[j].port.high = pf->rule.port.remote.high;
|
||||
j++; len += 5;
|
||||
}
|
||||
}
|
||||
|
||||
tft.pf[i].num_of_component = j;
|
||||
tft.pf[i].length = len;
|
||||
i++;
|
||||
|
||||
pf = pgw_pf_next(pf);
|
||||
}
|
||||
tft.num_of_packet_filter = i;
|
||||
|
||||
req->bearer_contexts.tft.presence = 1;
|
||||
gtp_build_tft(&req->bearer_contexts.tft,
|
||||
&tft, tft_buf, GTP_MAX_TRAFFIC_FLOW_TEMPLATE);
|
||||
|
||||
gtp_message.h.type = type;
|
||||
rv = gtp_build_msg(pkbuf, >p_message);
|
||||
d_assert(rv == CORE_OK, return CORE_ERROR, "gtp build failed");
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t pgw_s5c_build_delete_bearer_request(
|
||||
pkbuf_t **pkbuf, c_uint8_t type, pgw_bearer_t *bearer)
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@ CORE_DECLARE(status_t) pgw_s5c_build_delete_session_response(
|
|||
|
||||
CORE_DECLARE(status_t) pgw_s5c_build_create_bearer_request(
|
||||
pkbuf_t **pkbuf, c_uint8_t type, pgw_bearer_t *bearer);
|
||||
CORE_DECLARE(status_t) pgw_s5c_build_update_bearer_request(
|
||||
pkbuf_t **pkbuf, c_uint8_t type, pgw_bearer_t *bearer);
|
||||
CORE_DECLARE(status_t) pgw_s5c_build_delete_bearer_request(
|
||||
pkbuf_t **pkbuf, c_uint8_t type, pgw_bearer_t *bearer);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -285,6 +285,7 @@ static void volte_test1(abts_case *tc, void *data)
|
|||
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
||||
|
||||
core_sleep(time_from_msec(1000));
|
||||
|
||||
#if 0
|
||||
/* Send PDN disconnectivity request */
|
||||
rv = tests1ap_build_pdn_disconnectivity_request(&sendbuf, msgindex);
|
||||
|
|
Loading…
Reference in New Issue