[GTP2] Fixed handling multi-bearer messages(#1498)
This commit is contained in:
parent
41f743af62
commit
de2ecd6400
|
@ -30,6 +30,7 @@ extern "C" {
|
|||
|
||||
#define OGS_MAX_NUM_OF_SESS 4 /* Num of APN(Session) per UE */
|
||||
#define OGS_MAX_NUM_OF_BEARER 4 /* Num of Bearer per Session */
|
||||
#define OGS_BEARER_PER_UE 8 /* Num of Bearer per UE */
|
||||
#define OGS_MAX_NUM_OF_PACKET_BUFFER 64 /* Num of PacketBuffer per UE */
|
||||
|
||||
/*
|
||||
|
|
|
@ -32,7 +32,7 @@ struct ogs_list_s {
|
|||
struct ogs_list_s *prev, *next;
|
||||
};
|
||||
typedef struct ogs_list_s ogs_list_t;
|
||||
typedef struct ogs_list_s ogs_lnode_t;;
|
||||
typedef struct ogs_list_s ogs_lnode_t;
|
||||
|
||||
#define OGS_LIST(name) \
|
||||
ogs_list_t name = { NULL, NULL }
|
||||
|
@ -123,7 +123,7 @@ static ogs_inline void ogs_list_remove(ogs_list_t *list, void *lnode)
|
|||
{
|
||||
ogs_list_t *node = lnode;
|
||||
ogs_list_t *prev = node->prev;
|
||||
ogs_list_t *next = node->next;;
|
||||
ogs_list_t *next = node->next;
|
||||
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
/*******************************************************************************
|
||||
* This file had been created by gtp-tlv.py script v0.1.0
|
||||
* Please do not modify this file but regenerate it via script.
|
||||
* Created on: 2022-04-12 14:16:09.777673 by pespin
|
||||
* Created on: 2022-04-22 03:19:22.029355 by acetcom
|
||||
* from 29274-g30.docx
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -2166,6 +2166,7 @@ ogs_tlv_desc_t ogs_gtp2_tlv_desc_modify_bearer_request =
|
|||
&ogs_gtp2_tlv_desc_ambr_0,
|
||||
&ogs_gtp2_tlv_desc_delay_value_0,
|
||||
&ogs_gtp2_tlv_desc_bearer_context_0,
|
||||
&ogs_tlv_desc_more8,
|
||||
&ogs_gtp2_tlv_desc_bearer_context_1,
|
||||
&ogs_gtp2_tlv_desc_recovery_0,
|
||||
&ogs_gtp2_tlv_desc_ue_time_zone_0,
|
||||
|
@ -2204,6 +2205,7 @@ ogs_tlv_desc_t ogs_gtp2_tlv_desc_modify_bearer_response =
|
|||
&ogs_gtp2_tlv_desc_apn_restriction_0,
|
||||
&ogs_gtp2_tlv_desc_pco_0,
|
||||
&ogs_gtp2_tlv_desc_bearer_context_0,
|
||||
&ogs_tlv_desc_more8,
|
||||
&ogs_gtp2_tlv_desc_bearer_context_1,
|
||||
&ogs_gtp2_tlv_desc_change_reporting_action_0,
|
||||
&ogs_gtp2_tlv_desc_csg_information_reporting_action_0,
|
||||
|
@ -2685,20 +2687,20 @@ ogs_tlv_desc_t ogs_gtp2_tlv_desc_modify_access_bearers_response =
|
|||
}};
|
||||
|
||||
|
||||
int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp_message, ogs_pkbuf_t *pkbuf)
|
||||
int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp2_message, ogs_pkbuf_t *pkbuf)
|
||||
{
|
||||
int rv = OGS_ERROR;
|
||||
ogs_gtp2_header_t *h = NULL;
|
||||
uint16_t size = 0;
|
||||
|
||||
ogs_assert(gtp_message);
|
||||
ogs_assert(gtp2_message);
|
||||
ogs_assert(pkbuf);
|
||||
ogs_assert(pkbuf->len);
|
||||
|
||||
h = (ogs_gtp2_header_t *)pkbuf->data;
|
||||
ogs_assert(h);
|
||||
|
||||
memset(gtp_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
memset(gtp2_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
if (h->teid_presence)
|
||||
size = OGS_GTPV2C_HEADER_LEN;
|
||||
|
@ -2706,143 +2708,143 @@ int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp_message, ogs_pkbuf_t *pkbuf)
|
|||
size = OGS_GTPV2C_HEADER_LEN-OGS_GTP2_TEID_LEN;
|
||||
|
||||
ogs_assert(ogs_pkbuf_pull(pkbuf, size));
|
||||
memcpy(>p_message->h, pkbuf->data - size, size);
|
||||
memcpy(>p2_message->h, pkbuf->data - size, size);
|
||||
|
||||
if (h->teid_presence)
|
||||
gtp_message->h.teid = be32toh(gtp_message->h.teid);
|
||||
gtp2_message->h.teid = be32toh(gtp2_message->h.teid);
|
||||
|
||||
if (pkbuf->len == 0) {
|
||||
ogs_assert(ogs_pkbuf_push(pkbuf, size));
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
switch(gtp_message->h.type) {
|
||||
switch(gtp2_message->h.type) {
|
||||
case OGS_GTP2_ECHO_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->echo_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->echo_request,
|
||||
&ogs_gtp2_tlv_desc_echo_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_ECHO_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->echo_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->echo_response,
|
||||
&ogs_gtp2_tlv_desc_echo_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->create_session_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->create_session_request,
|
||||
&ogs_gtp2_tlv_desc_create_session_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->create_session_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->create_session_response,
|
||||
&ogs_gtp2_tlv_desc_create_session_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->modify_bearer_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->modify_bearer_request,
|
||||
&ogs_gtp2_tlv_desc_modify_bearer_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->modify_bearer_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->modify_bearer_response,
|
||||
&ogs_gtp2_tlv_desc_modify_bearer_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_session_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_session_request,
|
||||
&ogs_gtp2_tlv_desc_delete_session_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_session_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_session_response,
|
||||
&ogs_gtp2_tlv_desc_delete_session_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_COMMAND_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->modify_bearer_command,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->modify_bearer_command,
|
||||
&ogs_gtp2_tlv_desc_modify_bearer_command, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_FAILURE_INDICATION_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->modify_bearer_failure_indication,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->modify_bearer_failure_indication,
|
||||
&ogs_gtp2_tlv_desc_modify_bearer_failure_indication, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_COMMAND_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_bearer_command,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_bearer_command,
|
||||
&ogs_gtp2_tlv_desc_delete_bearer_command, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_FAILURE_INDICATION_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_bearer_failure_indication,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_bearer_failure_indication,
|
||||
&ogs_gtp2_tlv_desc_delete_bearer_failure_indication, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->bearer_resource_command,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->bearer_resource_command,
|
||||
&ogs_gtp2_tlv_desc_bearer_resource_command, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->bearer_resource_failure_indication,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->bearer_resource_failure_indication,
|
||||
&ogs_gtp2_tlv_desc_bearer_resource_failure_indication, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_FAILURE_INDICATION_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->downlink_data_notification_failure_indication,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->downlink_data_notification_failure_indication,
|
||||
&ogs_gtp2_tlv_desc_downlink_data_notification_failure_indication, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->create_bearer_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->create_bearer_request,
|
||||
&ogs_gtp2_tlv_desc_create_bearer_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->create_bearer_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->create_bearer_response,
|
||||
&ogs_gtp2_tlv_desc_create_bearer_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->update_bearer_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->update_bearer_request,
|
||||
&ogs_gtp2_tlv_desc_update_bearer_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->update_bearer_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->update_bearer_response,
|
||||
&ogs_gtp2_tlv_desc_update_bearer_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_bearer_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_bearer_request,
|
||||
&ogs_gtp2_tlv_desc_delete_bearer_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_bearer_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_bearer_response,
|
||||
&ogs_gtp2_tlv_desc_delete_bearer_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->create_indirect_data_forwarding_tunnel_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->create_indirect_data_forwarding_tunnel_request,
|
||||
&ogs_gtp2_tlv_desc_create_indirect_data_forwarding_tunnel_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->create_indirect_data_forwarding_tunnel_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->create_indirect_data_forwarding_tunnel_response,
|
||||
&ogs_gtp2_tlv_desc_create_indirect_data_forwarding_tunnel_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_indirect_data_forwarding_tunnel_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_indirect_data_forwarding_tunnel_request,
|
||||
&ogs_gtp2_tlv_desc_delete_indirect_data_forwarding_tunnel_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->delete_indirect_data_forwarding_tunnel_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->delete_indirect_data_forwarding_tunnel_response,
|
||||
&ogs_gtp2_tlv_desc_delete_indirect_data_forwarding_tunnel_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->release_access_bearers_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->release_access_bearers_request,
|
||||
&ogs_gtp2_tlv_desc_release_access_bearers_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->release_access_bearers_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->release_access_bearers_response,
|
||||
&ogs_gtp2_tlv_desc_release_access_bearers_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->downlink_data_notification,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->downlink_data_notification,
|
||||
&ogs_gtp2_tlv_desc_downlink_data_notification, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->downlink_data_notification_acknowledge,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->downlink_data_notification_acknowledge,
|
||||
&ogs_gtp2_tlv_desc_downlink_data_notification_acknowledge, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_ACCESS_BEARERS_REQUEST_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->modify_access_bearers_request,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->modify_access_bearers_request,
|
||||
&ogs_gtp2_tlv_desc_modify_access_bearers_request, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_ACCESS_BEARERS_RESPONSE_TYPE:
|
||||
rv = ogs_tlv_parse_msg(>p_message->modify_access_bearers_response,
|
||||
rv = ogs_tlv_parse_msg(>p2_message->modify_access_bearers_response,
|
||||
&ogs_gtp2_tlv_desc_modify_access_bearers_response, pkbuf, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
default:
|
||||
ogs_warn("Not implmeneted(type:%d)", gtp_message->h.type);
|
||||
ogs_warn("Not implmeneted(type:%d)", gtp2_message->h.type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2851,138 +2853,138 @@ int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp_message, ogs_pkbuf_t *pkbuf)
|
|||
return rv;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *ogs_gtp2_build_msg(ogs_gtp2_message_t *gtp_message)
|
||||
ogs_pkbuf_t *ogs_gtp2_build_msg(ogs_gtp2_message_t *gtp2_message)
|
||||
{
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(gtp_message);
|
||||
switch(gtp_message->h.type) {
|
||||
ogs_assert(gtp2_message);
|
||||
switch(gtp2_message->h.type) {
|
||||
case OGS_GTP2_ECHO_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_echo_request,
|
||||
>p_message->echo_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->echo_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_ECHO_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_echo_response,
|
||||
>p_message->echo_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->echo_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_create_session_request,
|
||||
>p_message->create_session_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->create_session_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_create_session_response,
|
||||
>p_message->create_session_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->create_session_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_modify_bearer_request,
|
||||
>p_message->modify_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->modify_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_modify_bearer_response,
|
||||
>p_message->modify_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->modify_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_session_request,
|
||||
>p_message->delete_session_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_session_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_session_response,
|
||||
>p_message->delete_session_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_session_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_COMMAND_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_modify_bearer_command,
|
||||
>p_message->modify_bearer_command, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->modify_bearer_command, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_FAILURE_INDICATION_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_modify_bearer_failure_indication,
|
||||
>p_message->modify_bearer_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->modify_bearer_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_COMMAND_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_bearer_command,
|
||||
>p_message->delete_bearer_command, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_bearer_command, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_FAILURE_INDICATION_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_bearer_failure_indication,
|
||||
>p_message->delete_bearer_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_bearer_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_bearer_resource_command,
|
||||
>p_message->bearer_resource_command, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->bearer_resource_command, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_bearer_resource_failure_indication,
|
||||
>p_message->bearer_resource_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->bearer_resource_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_FAILURE_INDICATION_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_downlink_data_notification_failure_indication,
|
||||
>p_message->downlink_data_notification_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->downlink_data_notification_failure_indication, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_create_bearer_request,
|
||||
>p_message->create_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->create_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_create_bearer_response,
|
||||
>p_message->create_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->create_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_update_bearer_request,
|
||||
>p_message->update_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->update_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_update_bearer_response,
|
||||
>p_message->update_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->update_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_bearer_request,
|
||||
>p_message->delete_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_bearer_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_bearer_response,
|
||||
>p_message->delete_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_bearer_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_create_indirect_data_forwarding_tunnel_request,
|
||||
>p_message->create_indirect_data_forwarding_tunnel_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->create_indirect_data_forwarding_tunnel_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_create_indirect_data_forwarding_tunnel_response,
|
||||
>p_message->create_indirect_data_forwarding_tunnel_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->create_indirect_data_forwarding_tunnel_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_indirect_data_forwarding_tunnel_request,
|
||||
>p_message->delete_indirect_data_forwarding_tunnel_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_indirect_data_forwarding_tunnel_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_delete_indirect_data_forwarding_tunnel_response,
|
||||
>p_message->delete_indirect_data_forwarding_tunnel_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->delete_indirect_data_forwarding_tunnel_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_release_access_bearers_request,
|
||||
>p_message->release_access_bearers_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->release_access_bearers_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_release_access_bearers_response,
|
||||
>p_message->release_access_bearers_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->release_access_bearers_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_downlink_data_notification,
|
||||
>p_message->downlink_data_notification, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->downlink_data_notification, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_downlink_data_notification_acknowledge,
|
||||
>p_message->downlink_data_notification_acknowledge, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->downlink_data_notification_acknowledge, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_ACCESS_BEARERS_REQUEST_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_modify_access_bearers_request,
|
||||
>p_message->modify_access_bearers_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->modify_access_bearers_request, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_ACCESS_BEARERS_RESPONSE_TYPE:
|
||||
pkbuf = ogs_tlv_build_msg(&ogs_gtp2_tlv_desc_modify_access_bearers_response,
|
||||
>p_message->modify_access_bearers_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
>p2_message->modify_access_bearers_response, OGS_TLV_MODE_T1_L2_I1);
|
||||
break;
|
||||
default:
|
||||
ogs_warn("Not implmeneted(type:%d)", gtp_message->h.type);
|
||||
ogs_warn("Not implmeneted(type:%d)", gtp2_message->h.type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
/*******************************************************************************
|
||||
* This file had been created by gtp-tlv.py script v0.1.0
|
||||
* Please do not modify this file but regenerate it via script.
|
||||
* Created on: 2022-04-12 14:16:09.770077 by pespin
|
||||
* Created on: 2022-04-22 03:19:22.024556 by acetcom
|
||||
* from 29274-g30.docx
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -851,7 +851,7 @@ typedef struct ogs_gtp2_modify_bearer_request_s {
|
|||
ogs_gtp2_tlv_f_teid_t sender_f_teid_for_control_plane;
|
||||
ogs_gtp2_tlv_ambr_t aggregate_maximum_bit_rate;
|
||||
ogs_gtp2_tlv_delay_value_t delay_downlink_packet_notification_request;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_modified;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_modified[8];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_removed;
|
||||
ogs_gtp2_tlv_recovery_t recovery;
|
||||
ogs_gtp2_tlv_ue_time_zone_t ue_time_zone;
|
||||
|
@ -884,7 +884,7 @@ typedef struct ogs_gtp2_modify_bearer_response_s {
|
|||
ogs_gtp2_tlv_ebi_t linked_eps_bearer_id;
|
||||
ogs_gtp2_tlv_apn_restriction_t apn_restriction;
|
||||
ogs_gtp2_tlv_pco_t protocol_configuration_options;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_modified;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_modified[8];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_marked_for_removal;
|
||||
ogs_gtp2_tlv_change_reporting_action_t change_reporting_action;
|
||||
ogs_gtp2_tlv_csg_information_reporting_action_t csg_information_reporting_action;
|
||||
|
|
|
@ -580,7 +580,7 @@ for (k, v) in sorted_msg_list:
|
|||
if "ies" in msg_list[k]:
|
||||
f.write("typedef struct ogs_gtp2_" + v_lower(k) + "_s {\n")
|
||||
for ies in msg_list[k]["ies"]:
|
||||
if (k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts':
|
||||
if ((k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts') or (k == 'Modify Bearer Request' and ies["ie_value"] == 'Bearer Contexts to be modified') or (k == 'Modify Bearer Response' and ies["ie_value"] == 'Bearer Contexts modified'):
|
||||
f.write(" ogs_gtp2_tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
||||
v_lower(ies["ie_value"]) + "[8];\n")
|
||||
else:
|
||||
|
@ -671,13 +671,13 @@ for (k, v) in sorted_msg_list:
|
|||
f.write(" 0, 0, 0, 0, {\n")
|
||||
for ies in msg_list[k]["ies"]:
|
||||
f.write(" &ogs_gtp2_tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"])))
|
||||
if (k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts':
|
||||
if ((k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts') or (k == 'Modify Bearer Request' and ies["ie_value"] == 'Bearer Contexts to be modified') or (k == 'Modify Bearer Response' and ies["ie_value"] == 'Bearer Contexts modified'):
|
||||
f.write(" &ogs_tlv_desc_more8,\n")
|
||||
f.write(" NULL,\n")
|
||||
f.write("}};\n\n")
|
||||
f.write("\n")
|
||||
|
||||
f.write("""int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp_message, ogs_pkbuf_t *pkbuf)
|
||||
f.write("""int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp2_message, ogs_pkbuf_t *pkbuf)
|
||||
{
|
||||
int rv = OGS_ERROR;
|
||||
ogs_gtp2_header_t *h = NULL;
|
||||
|
@ -701,7 +701,7 @@ f.write("""int ogs_gtp2_parse_msg(ogs_gtp2_message_t *gtp_message, ogs_pkbuf_t *
|
|||
memcpy(>p2_message->h, pkbuf->data - size, size);
|
||||
|
||||
if (h->teid_presence)
|
||||
gtp2_message->h.teid = be32toh(gtp_message->h.teid);
|
||||
gtp2_message->h.teid = be32toh(gtp2_message->h.teid);
|
||||
|
||||
if (pkbuf->len == 0) {
|
||||
ogs_assert(ogs_pkbuf_push(pkbuf, size));
|
||||
|
@ -728,7 +728,7 @@ f.write(""" default:
|
|||
|
||||
""")
|
||||
|
||||
f.write("""ogs_pkbuf_t *ogs_gtp2_build_msg(ogs_gtp2_message_t *gtp_message)
|
||||
f.write("""ogs_pkbuf_t *ogs_gtp2_build_msg(ogs_gtp2_message_t *gtp2_message)
|
||||
{
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
|
@ -750,6 +750,4 @@ f.write(""" default:
|
|||
}
|
||||
""")
|
||||
|
||||
f.write("\n")
|
||||
|
||||
f.close()
|
||||
|
|
|
@ -115,6 +115,10 @@ typedef struct ogs_gtp_xact_s {
|
|||
#define OGS_GTP_CREATE_IN_UPLINK_NAS_TRANSPORT 2
|
||||
#define OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST 3
|
||||
int create_action;
|
||||
|
||||
#define OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST 1
|
||||
#define OGS_GTP_MODIFY_IN_E_RAB_MODIFICATION 2
|
||||
int modify_action;
|
||||
} ogs_gtp_xact_t;
|
||||
|
||||
int ogs_gtp_xact_init(void);
|
||||
|
|
|
@ -136,11 +136,14 @@ int ogs_pfcp_send_heartbeat_request(ogs_pfcp_node_t *node,
|
|||
h.type = OGS_PFCP_HEARTBEAT_REQUEST_TYPE;
|
||||
h.seid = 0;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
pkbuf = ogs_pfcp_build_heartbeat_request(h.type);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(node, &h, pkbuf, cb, node);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -186,11 +189,14 @@ int ogs_pfcp_cp_send_association_setup_request(ogs_pfcp_node_t *node,
|
|||
h.type = OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE;
|
||||
h.seid = 0;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
pkbuf = ogs_pfcp_cp_build_association_setup_request(h.type);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(node, &h, pkbuf, cb, node);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -237,11 +243,14 @@ int ogs_pfcp_up_send_association_setup_request(ogs_pfcp_node_t *node,
|
|||
h.type = OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE;
|
||||
h.seid = 0;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
pkbuf = ogs_pfcp_up_build_association_setup_request(h.type);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(node, &h, pkbuf, cb, node);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
|
|
@ -72,10 +72,8 @@ void ogs_pfcp_xact_final(void)
|
|||
}
|
||||
|
||||
ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
|
||||
ogs_pfcp_header_t *hdesc, ogs_pkbuf_t *pkbuf,
|
||||
void (*cb)(ogs_pfcp_xact_t *xact, void *data), void *data)
|
||||
{
|
||||
int rv;
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
|
||||
|
@ -109,12 +107,7 @@ ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
|
|||
ogs_list_add(xact->org == OGS_PFCP_LOCAL_ORIGINATOR ?
|
||||
&xact->node->local_list : &xact->node->remote_list, xact);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, hdesc, pkbuf);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("ogs_pfcp_xact_update_tx(rv=%d) failed", (int)rv);
|
||||
ogs_pfcp_xact_delete(xact);
|
||||
return NULL;
|
||||
}
|
||||
ogs_list_init(&xact->pdr_to_create_list);
|
||||
|
||||
ogs_debug("[%d] %s Create peer [%s]:%d",
|
||||
xact->xid,
|
||||
|
|
|
@ -33,6 +33,8 @@ extern "C" {
|
|||
*/
|
||||
typedef struct ogs_pfcp_xact_s {
|
||||
ogs_lnode_t lnode; /**< A node of list */
|
||||
ogs_lnode_t tmpnode; /**< A node of temp-list */
|
||||
|
||||
ogs_index_t index;
|
||||
|
||||
#define OGS_PFCP_LOCAL_ORIGINATOR 0
|
||||
|
@ -114,13 +116,13 @@ typedef struct ogs_pfcp_xact_s {
|
|||
int delete_trigger;
|
||||
|
||||
ogs_list_t pdr_to_create_list;
|
||||
ogs_list_t bearer_to_modify_list;
|
||||
} ogs_pfcp_xact_t;
|
||||
|
||||
int ogs_pfcp_xact_init(void);
|
||||
void ogs_pfcp_xact_final(void);
|
||||
|
||||
ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
|
||||
ogs_pfcp_header_t *hdesc, ogs_pkbuf_t *pkbuf,
|
||||
void (*cb)(ogs_pfcp_xact_t *xact, void *data), void *data);
|
||||
ogs_pfcp_xact_t *ogs_pfcp_xact_cycle(ogs_pfcp_xact_t *xact);
|
||||
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node);
|
||||
|
|
|
@ -2400,6 +2400,30 @@ void ngap_handle_path_switch_request(
|
|||
return;
|
||||
}
|
||||
|
||||
if (!UESecurityCapabilities) {
|
||||
ogs_error("No UESecurityCapabilities");
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PDUSessionResourceToBeSwitchedDLList) {
|
||||
ogs_error("No PDUSessionResourceToBeSwitchedDLList");
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SECURITY_CONTEXT_IS_VALID(amf_ue)) {
|
||||
ogs_error("No Security Context");
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_nas, NGAP_CauseNas_authentication_failure));
|
||||
return;
|
||||
}
|
||||
|
||||
ogs_info(" [NEW] RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld] ",
|
||||
ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id);
|
||||
|
||||
|
@ -2419,14 +2443,6 @@ void ngap_handle_path_switch_request(
|
|||
ogs_info(" [NEW] TAC[%d] CellID[0x%llx]",
|
||||
amf_ue->nr_tai.tac.v, (long long)amf_ue->nr_cgi.cell_id);
|
||||
|
||||
if (!UESecurityCapabilities) {
|
||||
ogs_error("No UESecurityCapabilities");
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
}
|
||||
|
||||
nRencryptionAlgorithms = &UESecurityCapabilities->nRencryptionAlgorithms;
|
||||
nRintegrityProtectionAlgorithms =
|
||||
&UESecurityCapabilities->nRintegrityProtectionAlgorithms;
|
||||
|
@ -2460,26 +2476,10 @@ void ngap_handle_path_switch_request(
|
|||
amf_ue->ue_security_capability.eutra_ia = eutra_ia >> 9;
|
||||
amf_ue->ue_security_capability.eutra_ia0 = eutra_ia0;
|
||||
|
||||
if (!SECURITY_CONTEXT_IS_VALID(amf_ue)) {
|
||||
ogs_error("No Security Context");
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_nas, NGAP_CauseNas_authentication_failure));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update Security Context (NextHop) */
|
||||
amf_ue->nhcc++;
|
||||
ogs_kdf_nh_gnb(amf_ue->kamf, amf_ue->nh, amf_ue->nh);
|
||||
|
||||
if (!PDUSessionResourceToBeSwitchedDLList) {
|
||||
ogs_error("No PDUSessionResourceToBeSwitchedDLList");
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < PDUSessionResourceToBeSwitchedDLList->list.count; i++) {
|
||||
amf_sess_t *sess = NULL;
|
||||
PDUSessionItem = (NGAP_PDUSessionResourceToBeSwitchedDLItem_t *)
|
||||
|
|
|
@ -179,8 +179,11 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
|
|||
/* Check if Initial Context Setup Response or
|
||||
* E-RAB Setup Response is received */
|
||||
if (MME_HAVE_ENB_S1U_PATH(bearer)) {
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
ogs_list_add(&mme_ue->bearer_to_modify_list,
|
||||
&bearer->to_modify_node);
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(bearer, 0));
|
||||
mme_gtp_send_modify_bearer_request(mme_ue, 0, 0));
|
||||
}
|
||||
|
||||
nas_eps_send_activate_all_dedicated_bearers(bearer);
|
||||
|
|
|
@ -45,6 +45,7 @@ static OGS_POOL(mme_csmap_pool, mme_csmap_t);
|
|||
static OGS_POOL(mme_enb_pool, mme_enb_t);
|
||||
static OGS_POOL(mme_ue_pool, mme_ue_t);
|
||||
static OGS_POOL(enb_ue_pool, enb_ue_t);
|
||||
static OGS_POOL(sgw_ue_pool, sgw_ue_t);
|
||||
static OGS_POOL(mme_sess_pool, mme_sess_t);
|
||||
static OGS_POOL(mme_bearer_pool, mme_bearer_t);
|
||||
|
||||
|
@ -58,6 +59,10 @@ static void stats_remove_enb_ue(void);
|
|||
static void stats_add_mme_session(void);
|
||||
static void stats_remove_mme_session(void);
|
||||
|
||||
static bool compare_ue_info(mme_sgw_t *node, enb_ue_t *enb_ue);
|
||||
static mme_sgw_t *selected_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue);
|
||||
static mme_sgw_t *changed_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue);
|
||||
|
||||
void mme_context_init()
|
||||
{
|
||||
ogs_assert(context_initialized == 0);
|
||||
|
@ -96,6 +101,7 @@ void mme_context_init()
|
|||
|
||||
ogs_pool_init(&mme_ue_pool, ogs_app()->max.ue);
|
||||
ogs_pool_init(&enb_ue_pool, ogs_app()->max.ue);
|
||||
ogs_pool_init(&sgw_ue_pool, ogs_app()->max.ue);
|
||||
ogs_pool_init(&mme_sess_pool, ogs_app()->pool.sess);
|
||||
ogs_pool_init(&mme_bearer_pool, ogs_app()->pool.bearer);
|
||||
ogs_pool_init(&self.m_tmsi, ogs_app()->max.ue);
|
||||
|
@ -141,6 +147,7 @@ void mme_context_final()
|
|||
ogs_pool_final(&mme_sess_pool);
|
||||
ogs_pool_final(&mme_ue_pool);
|
||||
ogs_pool_final(&enb_ue_pool);
|
||||
ogs_pool_final(&sgw_ue_pool);
|
||||
|
||||
ogs_pool_final(&mme_enb_pool);
|
||||
|
||||
|
@ -1557,6 +1564,8 @@ mme_sgw_t *mme_sgw_add(ogs_sockaddr_t *addr)
|
|||
ogs_list_init(&sgw->gnode.local_list);
|
||||
ogs_list_init(&sgw->gnode.remote_list);
|
||||
|
||||
ogs_list_init(&sgw->sgw_ue_list);
|
||||
|
||||
ogs_list_add(&self.sgw_list, sgw);
|
||||
|
||||
return sgw;
|
||||
|
@ -2019,6 +2028,112 @@ enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue)
|
|||
return ogs_pool_cycle(&enb_ue_pool, enb_ue);
|
||||
}
|
||||
|
||||
/** sgw_ue_context handling function */
|
||||
sgw_ue_t *sgw_ue_add(mme_sgw_t *sgw)
|
||||
{
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(sgw);
|
||||
|
||||
ogs_pool_alloc(&sgw_ue_pool, &sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
memset(sgw_ue, 0, sizeof *sgw_ue);
|
||||
|
||||
sgw_ue->index = ogs_pool_index(&sgw_ue_pool, sgw_ue);
|
||||
ogs_assert(sgw_ue->index > 0 && sgw_ue->index <= ogs_app()->max.ue);
|
||||
|
||||
sgw_ue->mme_s11_teid = sgw_ue->index;
|
||||
|
||||
sgw_ue->t_gtp2_holding = ogs_timer_add(
|
||||
ogs_app()->timer_mgr, mme_timer_s11_holding_timer_expire, sgw_ue);
|
||||
ogs_assert(sgw_ue->t_gtp2_holding);
|
||||
|
||||
sgw_ue->sgw = sgw;
|
||||
|
||||
ogs_list_add(&sgw->sgw_ue_list, sgw_ue);
|
||||
|
||||
return sgw_ue;
|
||||
}
|
||||
|
||||
void sgw_ue_remove(sgw_ue_t *sgw_ue)
|
||||
{
|
||||
mme_sgw_t *sgw = NULL;
|
||||
|
||||
ogs_assert(sgw_ue);
|
||||
sgw = sgw_ue->sgw;
|
||||
ogs_assert(sgw);
|
||||
|
||||
ogs_list_remove(&sgw->sgw_ue_list, sgw_ue);
|
||||
|
||||
ogs_assert(sgw_ue->t_gtp2_holding);
|
||||
ogs_timer_delete(sgw_ue->t_gtp2_holding);
|
||||
|
||||
ogs_pool_free(&sgw_ue_pool, sgw_ue);
|
||||
}
|
||||
|
||||
void sgw_ue_switch_to_sgw(sgw_ue_t *sgw_ue, mme_sgw_t *new_sgw)
|
||||
{
|
||||
ogs_assert(sgw_ue);
|
||||
ogs_assert(sgw_ue->sgw);
|
||||
ogs_assert(new_sgw);
|
||||
|
||||
/* Remove from the old sgw */
|
||||
ogs_list_remove(&sgw_ue->sgw->sgw_ue_list, sgw_ue);
|
||||
|
||||
/* Add to the new sgw */
|
||||
ogs_list_add(&new_sgw->sgw_ue_list, sgw_ue);
|
||||
|
||||
/* Switch to sgw */
|
||||
sgw_ue->sgw = new_sgw;
|
||||
}
|
||||
|
||||
sgw_ue_t *sgw_ue_find(uint32_t index)
|
||||
{
|
||||
return ogs_pool_find(&sgw_ue_pool, index);
|
||||
}
|
||||
|
||||
sgw_ue_t *sgw_ue_find_by_mme_s11_teid(uint32_t mme_s11_teid)
|
||||
{
|
||||
return sgw_ue_find(mme_s11_teid);
|
||||
}
|
||||
|
||||
sgw_ue_t *sgw_ue_cycle(sgw_ue_t *sgw_ue)
|
||||
{
|
||||
return ogs_pool_cycle(&sgw_ue_pool, sgw_ue);
|
||||
}
|
||||
|
||||
sgw_relocation_e sgw_ue_check_if_relocated(mme_ue_t *mme_ue)
|
||||
{
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
sgw_ue_t *source_ue, *target_ue = NULL;
|
||||
mme_sgw_t *current = NULL, *changed = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
||||
ogs_assert(enb_ue);
|
||||
source_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(source_ue);
|
||||
|
||||
current = source_ue->sgw;
|
||||
ogs_assert(current);
|
||||
|
||||
changed = changed_sgw_node(current, enb_ue);
|
||||
if (!changed) return SGW_WITHOUT_RELOCATION;
|
||||
|
||||
target_ue = sgw_ue_cycle(source_ue->target_ue);
|
||||
if (target_ue) {
|
||||
ogs_error("SGW-UE source has already been associated with target");
|
||||
return SGW_HAS_ALREADY_BEEN_RELOCATED;
|
||||
}
|
||||
|
||||
target_ue = sgw_ue_add(changed);
|
||||
ogs_assert(target_ue);
|
||||
|
||||
sgw_ue_source_associate_target(source_ue, target_ue);
|
||||
|
||||
return SGW_WITH_RELOCATION;
|
||||
}
|
||||
|
||||
void mme_ue_new_guti(mme_ue_t *mme_ue)
|
||||
{
|
||||
served_gummei_t *served_gummei = NULL;
|
||||
|
@ -2111,7 +2226,7 @@ static mme_sgw_t *selected_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue)
|
|||
return next ? next : ogs_list_first(&mme_self()->sgw_list);
|
||||
}
|
||||
|
||||
mme_sgw_t *mme_changed_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue)
|
||||
static mme_sgw_t *changed_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue)
|
||||
{
|
||||
mme_sgw_t *changed = NULL;
|
||||
|
||||
|
@ -2129,6 +2244,7 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
|
|||
{
|
||||
mme_enb_t *enb = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
|
||||
|
@ -2144,10 +2260,6 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
|
|||
|
||||
ogs_list_init(&mme_ue->sess_list);
|
||||
|
||||
mme_ue->mme_s11_teid = ogs_pool_index(&mme_ue_pool, mme_ue);
|
||||
ogs_assert(mme_ue->mme_s11_teid > 0 &&
|
||||
mme_ue->mme_s11_teid <= ogs_app()->max.ue);
|
||||
|
||||
/*
|
||||
* When used for the first time, if last node is set,
|
||||
* the search is performed from the first SGW in a round-robin manner.
|
||||
|
@ -2156,10 +2268,16 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue)
|
|||
mme_self()->sgw = ogs_list_last(&mme_self()->sgw_list);
|
||||
|
||||
/* setup GTP path with selected SGW */
|
||||
mme_ue->sgw = mme_self()->sgw = selected_sgw_node(mme_self()->sgw, enb_ue);
|
||||
ogs_assert(mme_ue->sgw);
|
||||
ogs_assert(mme_ue->gnode);
|
||||
ogs_debug("UE using SGW on IP[%s]", OGS_ADDR(mme_ue->gnode->sa_list, buf));
|
||||
mme_self()->sgw = selected_sgw_node(mme_self()->sgw, enb_ue);
|
||||
ogs_assert(mme_self()->sgw);
|
||||
|
||||
sgw_ue = sgw_ue_add(mme_self()->sgw);
|
||||
ogs_assert(sgw_ue);
|
||||
ogs_assert(sgw_ue->gnode);
|
||||
|
||||
sgw_ue_associate_mme_ue(sgw_ue, mme_ue);
|
||||
|
||||
ogs_debug("UE using SGW on IP[%s]", OGS_ADDR(sgw_ue->gnode->sa_list, buf));
|
||||
|
||||
/* Clear VLR */
|
||||
mme_ue->csmap = NULL;
|
||||
|
@ -2213,6 +2331,9 @@ void mme_ue_remove(mme_ue_t *mme_ue)
|
|||
|
||||
mme_ue_fsm_fini(mme_ue);
|
||||
|
||||
ogs_assert(mme_ue->sgw_ue);
|
||||
sgw_ue_remove(mme_ue->sgw_ue);
|
||||
|
||||
if (mme_ue->current.m_tmsi)
|
||||
ogs_assert(mme_m_tmsi_free(mme_ue->current.m_tmsi) == OGS_OK);
|
||||
|
||||
|
@ -2239,7 +2360,7 @@ void mme_ue_remove(mme_ue_t *mme_ue)
|
|||
ogs_timer_delete(mme_ue->t3460.timer);
|
||||
ogs_timer_delete(mme_ue->t3470.timer);
|
||||
|
||||
mme_ue_deassociate(mme_ue);
|
||||
enb_ue_unlink(mme_ue);
|
||||
|
||||
mme_sess_remove_all(mme_ue);
|
||||
mme_session_remove_all(mme_ue);
|
||||
|
@ -2317,11 +2438,6 @@ mme_ue_t *mme_ue_find_by_guti(ogs_nas_eps_guti_t *guti)
|
|||
self.guti_ue_hash, guti, sizeof(ogs_nas_eps_guti_t));
|
||||
}
|
||||
|
||||
mme_ue_t *mme_ue_find_by_teid(uint32_t teid)
|
||||
{
|
||||
return ogs_pool_find(&mme_ue_pool, teid);
|
||||
}
|
||||
|
||||
mme_ue_t *mme_ue_find_by_message(ogs_nas_eps_message_t *message)
|
||||
{
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
@ -2598,7 +2714,7 @@ bool mme_ue_have_active_eps_bearers(mme_ue_t *mme_ue)
|
|||
return false;
|
||||
}
|
||||
|
||||
void mme_ue_associate_enb_ue(mme_ue_t *mme_ue, enb_ue_t *enb_ue)
|
||||
void enb_ue_associate_mme_ue(enb_ue_t *enb_ue, mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(enb_ue);
|
||||
|
@ -2613,14 +2729,13 @@ void enb_ue_deassociate(enb_ue_t *enb_ue)
|
|||
enb_ue->mme_ue = NULL;
|
||||
}
|
||||
|
||||
void mme_ue_deassociate(mme_ue_t *mme_ue)
|
||||
void enb_ue_unlink(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_assert(mme_ue);
|
||||
mme_ue->enb_ue = NULL;
|
||||
}
|
||||
|
||||
void source_ue_associate_target_ue(
|
||||
enb_ue_t *source_ue, enb_ue_t *target_ue)
|
||||
void enb_ue_source_associate_target(enb_ue_t *source_ue, enb_ue_t *target_ue)
|
||||
{
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
|
@ -2634,7 +2749,7 @@ void source_ue_associate_target_ue(
|
|||
source_ue->target_ue = target_ue;
|
||||
}
|
||||
|
||||
void source_ue_deassociate_target_ue(enb_ue_t *enb_ue)
|
||||
void enb_ue_source_deassociate_target(enb_ue_t *enb_ue)
|
||||
{
|
||||
enb_ue_t *source_ue = NULL;
|
||||
enb_ue_t *target_ue = NULL;
|
||||
|
@ -2659,6 +2774,66 @@ void source_ue_deassociate_target_ue(enb_ue_t *enb_ue)
|
|||
}
|
||||
}
|
||||
|
||||
void sgw_ue_associate_mme_ue(sgw_ue_t *sgw_ue, mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
mme_ue->sgw_ue = sgw_ue;
|
||||
sgw_ue->mme_ue = mme_ue;
|
||||
}
|
||||
|
||||
void sgw_ue_deassociate(sgw_ue_t *sgw_ue)
|
||||
{
|
||||
ogs_assert(sgw_ue);
|
||||
sgw_ue->mme_ue = NULL;
|
||||
}
|
||||
|
||||
void sgw_ue_unlink(mme_ue_t *mme_ue)
|
||||
{
|
||||
ogs_assert(mme_ue);
|
||||
mme_ue->sgw_ue = NULL;
|
||||
}
|
||||
|
||||
void sgw_ue_source_associate_target(sgw_ue_t *source_ue, sgw_ue_t *target_ue)
|
||||
{
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
ogs_assert(source_ue);
|
||||
ogs_assert(target_ue);
|
||||
mme_ue = source_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
target_ue->mme_ue = mme_ue;
|
||||
target_ue->source_ue = source_ue;
|
||||
source_ue->target_ue = target_ue;
|
||||
}
|
||||
|
||||
void sgw_ue_source_deassociate_target(sgw_ue_t *sgw_ue)
|
||||
{
|
||||
sgw_ue_t *source_ue = NULL;
|
||||
sgw_ue_t *target_ue = NULL;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (sgw_ue->target_ue) {
|
||||
source_ue = sgw_ue;
|
||||
target_ue = sgw_ue->target_ue;
|
||||
|
||||
ogs_assert(source_ue->target_ue);
|
||||
ogs_assert(target_ue->source_ue);
|
||||
source_ue->target_ue = NULL;
|
||||
target_ue->source_ue = NULL;
|
||||
} else if (sgw_ue->source_ue) {
|
||||
target_ue = sgw_ue;
|
||||
source_ue = sgw_ue->source_ue;
|
||||
|
||||
ogs_assert(source_ue->target_ue);
|
||||
ogs_assert(target_ue->source_ue);
|
||||
source_ue->target_ue = NULL;
|
||||
target_ue->source_ue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mme_sess_t *mme_sess_add(mme_ue_t *mme_ue, uint8_t pti)
|
||||
{
|
||||
mme_sess_t *sess = NULL;
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct mme_vlr_s mme_vlr_t;
|
|||
typedef struct mme_csmap_s mme_csmap_t;
|
||||
|
||||
typedef struct enb_ue_s enb_ue_t;
|
||||
typedef struct sgw_ue_s sgw_ue_t;
|
||||
typedef struct mme_ue_s mme_ue_t;
|
||||
typedef struct mme_sess_s mme_sess_t;
|
||||
typedef struct mme_bearer_s mme_bearer_t;
|
||||
|
@ -153,6 +154,8 @@ typedef struct mme_sgw_s {
|
|||
uint8_t num_of_tac;
|
||||
uint32_t e_cell_id[OGS_MAX_NUM_OF_CELL_ID];
|
||||
uint8_t num_of_e_cell_id;
|
||||
|
||||
ogs_list_t sgw_ue_list;
|
||||
} mme_sgw_t;
|
||||
|
||||
typedef struct mme_pgw_s {
|
||||
|
@ -266,6 +269,36 @@ struct enb_ue_s {
|
|||
mme_ue_t *mme_ue;
|
||||
};
|
||||
|
||||
struct sgw_ue_s {
|
||||
ogs_lnode_t lnode;
|
||||
uint32_t index;
|
||||
|
||||
sgw_ue_t *source_ue;
|
||||
sgw_ue_t *target_ue;
|
||||
|
||||
/* UE identity */
|
||||
uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */
|
||||
uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */
|
||||
|
||||
/*
|
||||
* If the MME sends Delete-Session-Request to the SGW for all sessions,
|
||||
* session_context_will_deleted = 1
|
||||
* When the MME receives a Delete-Session-Response for the last session,
|
||||
* session_context_will_deleted = 0
|
||||
*/
|
||||
int session_context_will_deleted;
|
||||
|
||||
/* GTPv2-C Holding timer for removing this context */
|
||||
ogs_timer_t *t_gtp2_holding;
|
||||
|
||||
/* Related Context */
|
||||
union {
|
||||
mme_sgw_t *sgw;
|
||||
ogs_gtp_node_t *gnode;
|
||||
};
|
||||
mme_ue_t *mme_ue;
|
||||
};
|
||||
|
||||
struct mme_ue_s {
|
||||
ogs_lnode_t lnode;
|
||||
ogs_fsm_t sm; /* A state machine */
|
||||
|
@ -318,9 +351,6 @@ struct mme_ue_s {
|
|||
ogs_nas_eps_guti_t guti;
|
||||
} current, next;
|
||||
|
||||
uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */
|
||||
uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */
|
||||
|
||||
uint16_t vlr_ostream_id; /* SCTP output stream id for VLR */
|
||||
|
||||
/* UE Info */
|
||||
|
@ -417,6 +447,9 @@ struct mme_ue_s {
|
|||
(((__mME)->enb_ue == NULL) || (enb_ue_cycle((__mME)->enb_ue) == NULL)))
|
||||
enb_ue_t *enb_ue; /* S1 UE context */
|
||||
|
||||
/* SGW UE context */
|
||||
sgw_ue_t *sgw_ue;
|
||||
|
||||
/* Save PDN Connectivity Request */
|
||||
ogs_nas_esm_message_container_t pdn_connectivity_request;
|
||||
|
||||
|
@ -507,32 +540,23 @@ struct mme_ue_s {
|
|||
uint8_t response;
|
||||
} gtp_counter[MAX_NUM_OF_GTP_COUNTER];
|
||||
|
||||
/*
|
||||
* If the MME sends Delete-Session-Request to the SGW for all sessions,
|
||||
* session_context_will_deleted = 1
|
||||
* When the MME receives a Delete-Session-Response for the last session,
|
||||
* session_context_will_deleted = 0
|
||||
*/
|
||||
int session_context_will_deleted;
|
||||
ogs_list_t bearer_to_modify_list;
|
||||
|
||||
union {
|
||||
mme_sgw_t *sgw;
|
||||
ogs_gtp_node_t *gnode;
|
||||
};
|
||||
mme_csmap_t *csmap;
|
||||
};
|
||||
|
||||
#define SESSION_CONTEXT_IS_AVAILABLE(__mME) \
|
||||
((__mME) && ((__mME)->sgw_s11_teid))
|
||||
((__mME) && ((__mME)->sgw_ue) && (((__mME)->sgw_ue)->sgw_s11_teid))
|
||||
|
||||
#define SESSION_CONTEXT_WILL_DELETED(__mME) \
|
||||
((__mME) && ((__mME)->session_context_will_deleted))
|
||||
((__mME) && ((__mME)->sgw_ue) && \
|
||||
(((__mME)->sgw_ue)->session_context_will_deleted))
|
||||
|
||||
#define CLEAR_SESSION_CONTEXT(__mME) \
|
||||
do { \
|
||||
ogs_assert((__mME)); \
|
||||
(__mME)->sgw_s11_teid = 0; \
|
||||
(__mME)->session_context_will_deleted = 0; \
|
||||
((__mME)->sgw_ue)->sgw_s11_teid = 0; \
|
||||
((__mME)->sgw_ue)->session_context_will_deleted = 0; \
|
||||
} while(0)
|
||||
|
||||
#define ACTIVE_EPS_BEARERS_IS_AVAIABLE(__mME) \
|
||||
|
@ -542,6 +566,8 @@ typedef struct mme_sess_s {
|
|||
|
||||
uint8_t pti; /* Procedure Trasaction Identity */
|
||||
|
||||
uint32_t pgw_s5c_teid;
|
||||
|
||||
/* PDN Connectivity Request */
|
||||
ogs_nas_request_type_t request_type;
|
||||
|
||||
|
@ -549,9 +575,9 @@ typedef struct mme_sess_s {
|
|||
ogs_list_t bearer_list;
|
||||
|
||||
/* Related Context */
|
||||
mme_ue_t *mme_ue;
|
||||
mme_ue_t *mme_ue;
|
||||
|
||||
ogs_session_t *session;
|
||||
ogs_session_t *session;
|
||||
|
||||
/* Save Protocol Configuration Options from UE */
|
||||
struct {
|
||||
|
@ -600,6 +626,8 @@ typedef struct mme_sess_s {
|
|||
} while(0)
|
||||
typedef struct mme_bearer_s {
|
||||
ogs_lnode_t lnode;
|
||||
ogs_lnode_t to_modify_node;
|
||||
|
||||
uint32_t index;
|
||||
ogs_fsm_t sm; /* State Machine */
|
||||
|
||||
|
@ -702,6 +730,20 @@ enb_ue_t *enb_ue_find(uint32_t index);
|
|||
enb_ue_t *enb_ue_find_by_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id);
|
||||
enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue);
|
||||
|
||||
sgw_ue_t *sgw_ue_add(mme_sgw_t *sgw);
|
||||
void sgw_ue_remove(sgw_ue_t *sgw_ue);
|
||||
void sgw_ue_switch_to_sgw(sgw_ue_t *sgw_ue, mme_sgw_t *new_sgw);
|
||||
sgw_ue_t *sgw_ue_find(uint32_t index);
|
||||
sgw_ue_t *sgw_ue_find_by_mme_s11_teid(uint32_t mme_s11_teid);
|
||||
sgw_ue_t *sgw_ue_cycle(sgw_ue_t *sgw_ue);
|
||||
|
||||
typedef enum {
|
||||
SGW_WITHOUT_RELOCATION = 1,
|
||||
SGW_WITH_RELOCATION = 2,
|
||||
SGW_HAS_ALREADY_BEEN_RELOCATED = 3,
|
||||
} sgw_relocation_e;
|
||||
sgw_relocation_e sgw_ue_check_if_relocated(mme_ue_t *mme_ue);
|
||||
|
||||
void mme_ue_new_guti(mme_ue_t *mme_ue);
|
||||
void mme_ue_confirm_guti(mme_ue_t *mme_ue);
|
||||
|
||||
|
@ -716,7 +758,6 @@ void mme_ue_fsm_fini(mme_ue_t *mme_ue);
|
|||
mme_ue_t *mme_ue_find_by_imsi(uint8_t *imsi, int imsi_len);
|
||||
mme_ue_t *mme_ue_find_by_imsi_bcd(char *imsi_bcd);
|
||||
mme_ue_t *mme_ue_find_by_guti(ogs_nas_eps_guti_t *nas_guti);
|
||||
mme_ue_t *mme_ue_find_by_teid(uint32_t teid);
|
||||
|
||||
mme_ue_t *mme_ue_find_by_message(ogs_nas_eps_message_t *message);
|
||||
int mme_ue_set_imsi(mme_ue_t *mme_ue, char *imsi_bcd);
|
||||
|
@ -734,23 +775,23 @@ bool mme_ue_have_active_eps_bearers(mme_ue_t *mme_ue);
|
|||
* ### MME_UE_ECM_CONNECTED() ###
|
||||
*
|
||||
* o RECV Initial Context Setup Failure in EMM Registered State
|
||||
* ### MME_UE_DEASSOCIATE_ENB_UE() ###
|
||||
* ### ENB_UE_DEASSOCIATE_MME_UE() ###
|
||||
* ### ENB_UE_REMOVE() ###
|
||||
* ### MME_UE_DEASSOCIATE() ###
|
||||
* ### ENB_UE_UNLINK() ###
|
||||
*
|
||||
* o SEND UE Context Release Command with NO_ACTION
|
||||
* o SEND UE Context Release Command with S1_REMOVE_AND_UNLINK
|
||||
* - RECV UE Context Release Complete
|
||||
* ### ENB_UE_REMOVE() ###
|
||||
* ### MME_UE_DEASSOCIATE() ###
|
||||
* ### ENB_UE_UNLINK() ###
|
||||
*
|
||||
* o SEND UE Context Release Command with REMOVE_MME_UE_CONTEXT
|
||||
* o SEND UE Context Release Command with UE_CONTEXT_REMOVE
|
||||
* - RECV UE Context Release Complete
|
||||
* ### ENB_UE_REMOVE() ###
|
||||
* ### MME_UE_REMOVE() ###
|
||||
*
|
||||
*
|
||||
* o RECV Handover Required
|
||||
* ### SOURCE_UE_ASSOCIATE_TARGET_UE() ####
|
||||
* ### ENB_UE_SOURCE_ASSOCIATE_TARGET() ####
|
||||
* - SEND Handover Request
|
||||
*
|
||||
* o RECV Handover Notify
|
||||
|
@ -758,27 +799,33 @@ bool mme_ue_have_active_eps_bearers(mme_ue_t *mme_ue);
|
|||
* ### MME_UE_ECM_CONNECTED(TARGET) ###
|
||||
* - Modify Bearer Request/Response
|
||||
* - UE Context Release Command/Complete
|
||||
* ### SOURCE_UE_DEASSOCIATE_TARGET_UE() ####
|
||||
* ### ENB_UE_SOURCE_DEASSOCIATE_TARGET() ####
|
||||
* ### ENB_UE_REMOVE() ####
|
||||
* - Delete Indirect Data Forwarding Tunnel Request/Response
|
||||
*
|
||||
* o RECV Handover Cancel
|
||||
* - UE Context Release Command/Complete
|
||||
* ### SOURCE_UE_DEASSOCIATE_TARGET_UE() ####
|
||||
* ### ENB_UE_SOURCE_DEASSOCIATE_TARGET() ####
|
||||
* ### ENB_UE_REMOVE() ####
|
||||
* - Delete Indirect Data Forwarding Tunnel Request/Response
|
||||
*
|
||||
* o RECV Handover Failure
|
||||
* - UE Context Release Command/Complete
|
||||
* ### SOURCE_UE_DEASSOCIATE_TARGET_UE() ####
|
||||
* ### ENB_UE_SOURCE_DEASSOCIATE_TARGET() ####
|
||||
* ### ENB_UE_REMOVE() ####
|
||||
* - Delete Indirect Data Forwarding Tunnel Request/Response
|
||||
*/
|
||||
void mme_ue_associate_enb_ue(mme_ue_t *mme_ue, enb_ue_t *enb_ue);
|
||||
void enb_ue_associate_mme_ue(enb_ue_t *enb_ue, mme_ue_t *mme_ue);
|
||||
void enb_ue_deassociate(enb_ue_t *enb_ue);
|
||||
void mme_ue_deassociate(mme_ue_t *mme_ue);
|
||||
void source_ue_associate_target_ue(enb_ue_t *source_ue, enb_ue_t *target_ue);
|
||||
void source_ue_deassociate_target_ue(enb_ue_t *enb_ue);
|
||||
void enb_ue_unlink(mme_ue_t *mme_ue);
|
||||
void enb_ue_source_associate_target(enb_ue_t *source_ue, enb_ue_t *target_ue);
|
||||
void enb_ue_source_deassociate_target(enb_ue_t *enb_ue);
|
||||
|
||||
void sgw_ue_associate_mme_ue(sgw_ue_t *sgw_ue, mme_ue_t *mme_ue);
|
||||
void sgw_ue_deassociate(sgw_ue_t *sgw_ue);
|
||||
void sgw_ue_unlink(mme_ue_t *mme_ue);
|
||||
void sgw_ue_source_associate_target(sgw_ue_t *source_ue, sgw_ue_t *target_ue);
|
||||
void sgw_ue_source_deassociate_target(sgw_ue_t *sgw_ue);
|
||||
|
||||
mme_sess_t *mme_sess_add(mme_ue_t *mme_ue, uint8_t pti);
|
||||
void mme_sess_remove(mme_sess_t *sess);
|
||||
|
@ -821,8 +868,6 @@ void mme_ebi_pool_clear(mme_ue_t *mme_ue);
|
|||
uint8_t mme_selected_int_algorithm(mme_ue_t *mme_ue);
|
||||
uint8_t mme_selected_enc_algorithm(mme_ue_t *mme_ue);
|
||||
|
||||
mme_sgw_t *mme_changed_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct ogs_diam_s6a_message_s ogs_diam_s6a_message_t;
|
|||
typedef struct mme_vlr_s mme_vlr_t;
|
||||
typedef struct mme_enb_s mme_enb_t;
|
||||
typedef struct enb_ue_s enb_ue_t;
|
||||
typedef struct sgw_ue_s sgw_ue_t;
|
||||
typedef struct mme_ue_s mme_ue_t;
|
||||
typedef struct mme_sess_s mme_sess_t;
|
||||
typedef struct mme_bearer_s mme_bearer_t;
|
||||
|
@ -91,6 +92,7 @@ typedef struct mme_event_s {
|
|||
mme_vlr_t *vlr;
|
||||
mme_enb_t *enb;
|
||||
enb_ue_t *enb_ue;
|
||||
sgw_ue_t *sgw_ue;
|
||||
mme_ue_t *mme_ue;
|
||||
mme_sess_t *sess;
|
||||
mme_bearer_t *bearer;
|
||||
|
|
|
@ -86,6 +86,7 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
type = xact->seq[0].type;
|
||||
|
||||
switch (type) {
|
||||
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
|
||||
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
||||
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
||||
|
@ -99,7 +100,6 @@ static void timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
|
||||
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
|
||||
bearer = data;
|
||||
ogs_assert(bearer);
|
||||
|
@ -206,18 +206,26 @@ int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action)
|
|||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
sgw_ue = sgw_ue_cycle(sgw_ue->target_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_create_session_request(h.type, sess);
|
||||
pkbuf = mme_s11_build_create_session_request(h.type, sess, create_action);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, sess);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->create_action = create_action;
|
||||
|
||||
|
@ -227,29 +235,31 @@ int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int mme_gtp_send_modify_bearer_request(mme_bearer_t *bearer, int uli_presence)
|
||||
int mme_gtp_send_modify_bearer_request(
|
||||
mme_ue_t *mme_ue, int uli_presence, int modify_action)
|
||||
{
|
||||
int rv;
|
||||
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_modify_bearer_request(h.type, bearer, uli_presence);
|
||||
pkbuf = mme_s11_build_modify_bearer_request(h.type, mme_ue, uli_presence);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, bearer);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->modify_action = modify_action;
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -264,20 +274,23 @@ int mme_gtp_send_delete_session_request(mme_sess_t *sess, int action)
|
|||
ogs_gtp2_header_t h;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(action);
|
||||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
s11buf = mme_s11_build_delete_session_request(h.type, sess);
|
||||
ogs_expect_or_return_val(s11buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, s11buf, timeout, sess);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, s11buf, timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->delete_action = action;
|
||||
|
||||
|
@ -290,8 +303,11 @@ int mme_gtp_send_delete_session_request(mme_sess_t *sess, int action)
|
|||
void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action)
|
||||
{
|
||||
mme_sess_t *sess = NULL, *next_sess = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
ogs_assert(action);
|
||||
|
||||
if (SESSION_CONTEXT_WILL_DELETED(mme_ue)) {
|
||||
|
@ -300,7 +316,7 @@ void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action)
|
|||
return;
|
||||
}
|
||||
|
||||
mme_ue->session_context_will_deleted = 1;
|
||||
sgw_ue->session_context_will_deleted = 1;
|
||||
|
||||
sess = mme_sess_first(mme_ue);
|
||||
while (sess != NULL) {
|
||||
|
@ -331,6 +347,7 @@ int mme_gtp_send_create_bearer_response(
|
|||
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
@ -338,12 +355,14 @@ int mme_gtp_send_create_bearer_response(
|
|||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
xact = ogs_gtp_xact_cycle(bearer->create.xact);
|
||||
ogs_assert(xact);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_create_bearer_response(h.type, bearer, cause_value);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
@ -364,6 +383,7 @@ int mme_gtp_send_update_bearer_response(
|
|||
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
@ -371,12 +391,14 @@ int mme_gtp_send_update_bearer_response(
|
|||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
xact = ogs_gtp_xact_cycle(bearer->update.xact);
|
||||
ogs_assert(xact);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_update_bearer_response(h.type, bearer, cause_value);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
@ -397,6 +419,7 @@ int mme_gtp_send_delete_bearer_response(
|
|||
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
@ -404,12 +427,14 @@ int mme_gtp_send_delete_bearer_response(
|
|||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
xact = ogs_gtp_xact_cycle(bearer->delete.xact);
|
||||
ogs_assert(xact);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_delete_bearer_response(h.type, bearer, cause_value);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
@ -429,18 +454,21 @@ int mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action)
|
|||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(action);
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_release_access_bearers_request(h.type);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->release_action = action;
|
||||
|
||||
|
@ -483,6 +511,7 @@ int mme_gtp_send_downlink_data_notification_ack(
|
|||
{
|
||||
int rv;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
|
@ -493,11 +522,13 @@ int mme_gtp_send_downlink_data_notification_ack(
|
|||
ogs_assert(xact);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
/* Build Downlink data notification ack */
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
s11buf = mme_s11_build_downlink_data_notification_ack(h.type, cause_value);
|
||||
ogs_expect_or_return_val(s11buf, OGS_ERROR);
|
||||
|
@ -518,18 +549,21 @@ int mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
|
|||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
||||
h.type, mme_ue);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
|
@ -545,19 +579,22 @@ int mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
|
|||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(action);
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_TLV_MAX_HEADROOM);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
ogs_pkbuf_reserve(pkbuf, OGS_TLV_MAX_HEADROOM);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->delete_indirect_action = action;
|
||||
|
||||
|
@ -576,19 +613,22 @@ int mme_gtp_send_bearer_resource_command(
|
|||
ogs_gtp_xact_t *xact = NULL;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE;
|
||||
h.teid = mme_ue->sgw_s11_teid;
|
||||
h.teid = sgw_ue->sgw_s11_teid;
|
||||
|
||||
pkbuf = mme_s11_build_bearer_resource_command(h.type, bearer, nas_message);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(mme_ue->gnode, &h, pkbuf, timeout, bearer);
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, bearer);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->xid |= OGS_GTP_CMD_XACT_ID;
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ int mme_gtp_open(void);
|
|||
void mme_gtp_close(void);
|
||||
|
||||
int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action);
|
||||
int mme_gtp_send_modify_bearer_request(mme_bearer_t *bearer, int uli_presence);
|
||||
int mme_gtp_send_modify_bearer_request(
|
||||
mme_ue_t *mme_ue, int uli_presence, int modify_action);
|
||||
int mme_gtp_send_delete_session_request(mme_sess_t *sess, int action);
|
||||
void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action);
|
||||
int mme_gtp_send_create_bearer_response(
|
||||
|
|
|
@ -22,14 +22,16 @@
|
|||
#include "mme-s11-build.h"
|
||||
|
||||
ogs_pkbuf_t *mme_s11_build_create_session_request(
|
||||
uint8_t type, mme_sess_t *sess)
|
||||
uint8_t type, mme_sess_t *sess, int create_action)
|
||||
{
|
||||
int rv;
|
||||
ogs_session_t *session = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_create_session_request_t *req = >p_message.create_session_request;
|
||||
ogs_gtp2_create_session_request_t *req =
|
||||
>p_message.create_session_request;
|
||||
|
||||
ogs_gtp2_uli_t uli;
|
||||
char uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
|
@ -53,10 +55,17 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
ogs_assert(bearer);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
sgw_ue = sgw_ue_cycle(sgw_ue->target_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
}
|
||||
|
||||
ogs_debug("Create Session Request");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
ogs_assert(mme_ue->imsi_len);
|
||||
|
@ -96,7 +105,7 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
|
||||
memset(&mme_s11_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
mme_s11_teid.interface_type = OGS_GTP2_F_TEID_S11_MME_GTP_C;
|
||||
mme_s11_teid.teid = htobe32(mme_ue->mme_s11_teid);
|
||||
mme_s11_teid.teid = htobe32(sgw_ue->mme_s11_teid);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
ogs_gtp_self()->gtpc_addr, ogs_gtp_self()->gtpc_addr6,
|
||||
&mme_s11_teid, &len);
|
||||
|
@ -107,6 +116,7 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
|
||||
memset(&pgw_s5c_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
pgw_s5c_teid.interface_type = OGS_GTP2_F_TEID_S5_S8_PGW_GTP_C;
|
||||
pgw_s5c_teid.teid = htobe32(sess->pgw_s5c_teid);
|
||||
if (session->smf_ip.ipv4 || session->smf_ip.ipv6) {
|
||||
pgw_s5c_teid.ipv4 = session->smf_ip.ipv4;
|
||||
pgw_s5c_teid.ipv6 = session->smf_ip.ipv6;
|
||||
|
@ -201,14 +211,14 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
indication.change_reporting_support_indication = 1;
|
||||
indication.enb_change_reporting_support_indication = 1;
|
||||
|
||||
if (req->pdn_type.u8 == OGS_PDU_SESSION_TYPE_IPV4V6) {
|
||||
if (req->pdn_type.u8 == OGS_PDU_SESSION_TYPE_IPV4V6)
|
||||
indication.dual_address_bearer_flag = 1;
|
||||
}
|
||||
|
||||
if (sess->request_type.value == OGS_NAS_EPS_REQUEST_TYPE_HANDOVER) {
|
||||
if (sess->request_type.value == OGS_NAS_EPS_REQUEST_TYPE_HANDOVER)
|
||||
indication.handover_indication = 1;
|
||||
req->indication_flags.presence = 1;
|
||||
}
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST)
|
||||
indication.operation_indication = 1;
|
||||
|
||||
session->paa.session_type = req->pdn_type.u8;
|
||||
req->pdn_address_allocation.data = &session->paa;
|
||||
|
@ -269,7 +279,8 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
if (time_exp.tm_gmtoff >= 0) {
|
||||
ue_timezone.timezone = OGS_GTP2_TIME_TO_BCD(time_exp.tm_gmtoff / 900);
|
||||
} else {
|
||||
ue_timezone.timezone = OGS_GTP2_TIME_TO_BCD((-time_exp.tm_gmtoff) / 900);
|
||||
ue_timezone.timezone =
|
||||
OGS_GTP2_TIME_TO_BCD((-time_exp.tm_gmtoff) / 900);
|
||||
ue_timezone.timezone |= 0x08;
|
||||
}
|
||||
/* quarters of an hour */
|
||||
|
@ -288,61 +299,80 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
}
|
||||
|
||||
ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
||||
uint8_t type, mme_bearer_t *bearer, int uli_presence)
|
||||
uint8_t type, mme_ue_t *mme_ue, int uli_presence)
|
||||
{
|
||||
int rv;
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_modify_bearer_request_t *req = >p_message.modify_bearer_request;
|
||||
ogs_gtp2_modify_bearer_request_t *req = NULL;
|
||||
|
||||
ogs_gtp2_f_teid_t enb_s1u_teid;
|
||||
int len;
|
||||
ogs_gtp2_f_teid_t enb_s1u_teid[OGS_BEARER_PER_UE];
|
||||
int len, i;
|
||||
ogs_gtp2_uli_t uli;
|
||||
char uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
|
||||
ogs_gtp2_indication_t indication;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_debug("Modifty Bearer Request");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d]",
|
||||
bearer->enb_s1u_teid, bearer->sgw_s1u_teid);
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
ogs_assert(ogs_list_count(&mme_ue->bearer_to_modify_list));
|
||||
|
||||
/* Initialize message */
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
req = >p_message.modify_bearer_request;
|
||||
|
||||
if (sess->request_type.value == OGS_NAS_EPS_REQUEST_TYPE_HANDOVER) {
|
||||
memset(&indication, 0, sizeof(ogs_gtp2_indication_t));
|
||||
indication.handover_indication = 1;
|
||||
req->indication_flags.presence = 1;
|
||||
req->indication_flags.data = &indication;
|
||||
req->indication_flags.len = sizeof(ogs_gtp2_indication_t);
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
i = 0;
|
||||
ogs_list_for_each_entry(
|
||||
&mme_ue->bearer_to_modify_list, bearer, to_modify_node) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d]",
|
||||
bearer->enb_s1u_teid, bearer->sgw_s1u_teid);
|
||||
|
||||
/* Bearer Context : EBI */
|
||||
req->bearer_contexts_to_be_modified[i].presence = 1;
|
||||
req->bearer_contexts_to_be_modified[i].eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
/* Data Plane(DL) : ENB-S1U */
|
||||
memset(&enb_s1u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
enb_s1u_teid[i].interface_type = OGS_GTP2_F_TEID_S1_U_ENODEB_GTP_U;
|
||||
enb_s1u_teid[i].teid = htobe32(bearer->enb_s1u_teid);
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_ip_to_f_teid(&bearer->enb_s1u_ip, &enb_s1u_teid[i], &len));
|
||||
req->bearer_contexts_to_be_modified[i].s1_u_enodeb_f_teid.presence = 1;
|
||||
req->bearer_contexts_to_be_modified[i].s1_u_enodeb_f_teid.data =
|
||||
&enb_s1u_teid[i];
|
||||
req->bearer_contexts_to_be_modified[i].s1_u_enodeb_f_teid.len = len;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Bearer Context : EBI */
|
||||
req->bearer_contexts_to_be_modified.presence = 1;
|
||||
req->bearer_contexts_to_be_modified.eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts_to_be_modified.eps_bearer_id.u8 = bearer->ebi;
|
||||
/* Indication */
|
||||
memset(&indication, 0, sizeof(ogs_gtp2_indication_t));
|
||||
ogs_list_for_each_entry(
|
||||
&mme_ue->bearer_to_modify_list, bearer, to_modify_node) {
|
||||
mme_sess_t *sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
/* Data Plane(DL) : ENB-S1U */
|
||||
memset(&enb_s1u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
enb_s1u_teid.interface_type = OGS_GTP2_F_TEID_S1_U_ENODEB_GTP_U;
|
||||
enb_s1u_teid.teid = htobe32(bearer->enb_s1u_teid);
|
||||
rv = ogs_gtp2_ip_to_f_teid(&bearer->enb_s1u_ip, &enb_s1u_teid, &len);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, NULL);
|
||||
req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.presence = 1;
|
||||
req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.data = &enb_s1u_teid;
|
||||
req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.len = len;
|
||||
if (sess->request_type.value == OGS_NAS_EPS_REQUEST_TYPE_HANDOVER) {
|
||||
indication.handover_indication = 1;
|
||||
req->indication_flags.presence = 1;
|
||||
req->indication_flags.data = &indication;
|
||||
req->indication_flags.len = sizeof(ogs_gtp2_indication_t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* User Location Information(ULI) */
|
||||
if (uli_presence) {
|
||||
/* User Location Information(ULI) */
|
||||
memset(&uli, 0, sizeof(ogs_gtp2_uli_t));
|
||||
uli.flags.e_cgi = 1;
|
||||
uli.flags.tai = 1;
|
||||
|
@ -382,7 +412,8 @@ ogs_pkbuf_t *mme_s11_build_delete_session_request(
|
|||
uint8_t type, mme_sess_t *sess)
|
||||
{
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_delete_session_request_t *req = >p_message.delete_session_request;
|
||||
ogs_gtp2_delete_session_request_t *req =
|
||||
>p_message.delete_session_request;
|
||||
|
||||
ogs_gtp2_uli_t uli;
|
||||
char uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
|
@ -390,16 +421,19 @@ ogs_pkbuf_t *mme_s11_build_delete_session_request(
|
|||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
bearer = mme_default_bearer_in_sess(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
ogs_debug("Delete Session Request");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -433,7 +467,8 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
|
|||
{
|
||||
int rv;
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_create_bearer_response_t *rsp = >p_message.create_bearer_response;
|
||||
ogs_gtp2_create_bearer_response_t *rsp =
|
||||
>p_message.create_bearer_response;
|
||||
|
||||
ogs_gtp2_cause_t cause;
|
||||
ogs_gtp2_f_teid_t enb_s1u_teid, sgw_s1u_teid;
|
||||
|
@ -445,14 +480,17 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
|
|||
struct tm time_exp;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug("Create Bearer Response");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -514,7 +552,8 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
|
|||
if (time_exp.tm_gmtoff >= 0) {
|
||||
ue_timezone.timezone = OGS_GTP2_TIME_TO_BCD(time_exp.tm_gmtoff / 900);
|
||||
} else {
|
||||
ue_timezone.timezone = OGS_GTP2_TIME_TO_BCD((-time_exp.tm_gmtoff) / 900);
|
||||
ue_timezone.timezone =
|
||||
OGS_GTP2_TIME_TO_BCD((-time_exp.tm_gmtoff) / 900);
|
||||
ue_timezone.timezone |= 0x08;
|
||||
}
|
||||
ue_timezone.daylight_saving_time =
|
||||
|
@ -531,7 +570,8 @@ ogs_pkbuf_t *mme_s11_build_update_bearer_response(
|
|||
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value)
|
||||
{
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_update_bearer_response_t *rsp = >p_message.update_bearer_response;
|
||||
ogs_gtp2_update_bearer_response_t *rsp =
|
||||
>p_message.update_bearer_response;
|
||||
|
||||
ogs_gtp2_cause_t cause;
|
||||
ogs_gtp2_uli_t uli;
|
||||
|
@ -541,14 +581,17 @@ ogs_pkbuf_t *mme_s11_build_update_bearer_response(
|
|||
struct tm time_exp;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug("Update Bearer Response");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -617,14 +660,17 @@ ogs_pkbuf_t *mme_s11_build_delete_bearer_response(
|
|||
struct tm time_exp;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
mme_ue = bearer->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug("Delete Bearer Response");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -762,6 +808,7 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
|||
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_create_indirect_data_forwarding_tunnel_request_t *req =
|
||||
|
@ -772,10 +819,12 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
|||
int len;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug("Create Indirect Data Forwarding Tunnel Request");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -843,6 +892,7 @@ ogs_pkbuf_t *mme_s11_build_bearer_resource_command(
|
|||
char flow_qos_buf[GTP2_FLOW_QOS_LEN];
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_bearer_t *linked_bearer = NULL;
|
||||
|
||||
|
@ -851,10 +901,12 @@ ogs_pkbuf_t *mme_s11_build_bearer_resource_command(
|
|||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug("Bearer Resource Command");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid);
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
ogs_assert(nas_message);
|
||||
switch (nas_message->esm.h.message_type) {
|
||||
|
|
|
@ -25,9 +25,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
ogs_pkbuf_t *mme_s11_build_create_session_request(
|
||||
uint8_t type, mme_sess_t *sess);
|
||||
uint8_t type, mme_sess_t *sess, int create_action);
|
||||
ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
||||
uint8_t type, mme_bearer_t *bearer, int uli_presense);
|
||||
uint8_t type, mme_ue_t *mme_ue, int uli_presense);
|
||||
ogs_pkbuf_t *mme_s11_build_delete_session_request(
|
||||
uint8_t type, mme_sess_t *sess);
|
||||
ogs_pkbuf_t *mme_s11_build_create_bearer_response(
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,39 +31,39 @@ void mme_s11_handle_echo_request(
|
|||
void mme_s11_handle_echo_response(
|
||||
ogs_gtp_xact_t *xact, ogs_gtp2_echo_response_t *rsp);
|
||||
void mme_s11_handle_create_session_response(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_create_session_response_t *rsp);
|
||||
void mme_s11_handle_modify_bearer_response(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_modify_bearer_response_t *rsp);
|
||||
void mme_s11_handle_delete_session_response(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_delete_session_response_t *rsp);
|
||||
void mme_s11_handle_create_bearer_request(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_create_bearer_request_t *rsp);
|
||||
void mme_s11_handle_update_bearer_request(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_update_bearer_request_t *rsp);
|
||||
void mme_s11_handle_delete_bearer_request(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_delete_bearer_request_t *rsp);
|
||||
|
||||
void mme_s11_handle_release_access_bearers_response(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_release_access_bearers_response_t *rsp);
|
||||
void mme_s11_handle_downlink_data_notification(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_downlink_data_notification_t *noti);
|
||||
void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp);
|
||||
void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp);
|
||||
|
||||
void mme_s11_handle_bearer_resource_failure_indication(
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp2_bearer_resource_failure_indication_t *ind);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -113,6 +113,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
|
||||
ogs_nas_eps_message_t nas_message;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
|
@ -338,7 +339,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
||||
S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE, 0));
|
||||
}
|
||||
mme_ue_associate_enb_ue(mme_ue, enb_ue);
|
||||
enb_ue_associate_mme_ue(enb_ue, mme_ue);
|
||||
}
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
@ -551,13 +552,12 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
*/
|
||||
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
||||
/* Cause is not "Context not found" */
|
||||
mme_ue = mme_ue_find_by_teid(gtp_message.h.teid);
|
||||
sgw_ue = sgw_ue_find_by_mme_s11_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
if (mme_ue) {
|
||||
gnode = mme_ue->gnode;
|
||||
if (sgw_ue) {
|
||||
gnode = sgw_ue->gnode;
|
||||
ogs_assert(gnode);
|
||||
|
||||
} else {
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
|
@ -578,57 +578,49 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
break;
|
||||
case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE:
|
||||
mme_s11_handle_create_session_response(
|
||||
xact, mme_ue, >p_message.create_session_response);
|
||||
xact, sgw_ue, >p_message.create_session_response);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE:
|
||||
mme_s11_handle_modify_bearer_response(
|
||||
xact, mme_ue, >p_message.modify_bearer_response);
|
||||
xact, sgw_ue, >p_message.modify_bearer_response);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
|
||||
mme_s11_handle_delete_session_response(
|
||||
xact, mme_ue, >p_message.delete_session_response);
|
||||
xact, sgw_ue, >p_message.delete_session_response);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
|
||||
mme_s11_handle_create_bearer_request(
|
||||
xact, mme_ue, >p_message.create_bearer_request);
|
||||
xact, sgw_ue, >p_message.create_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
|
||||
mme_s11_handle_update_bearer_request(
|
||||
xact, mme_ue, >p_message.update_bearer_request);
|
||||
xact, sgw_ue, >p_message.update_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
|
||||
mme_s11_handle_delete_bearer_request(
|
||||
xact, mme_ue, >p_message.delete_bearer_request);
|
||||
xact, sgw_ue, >p_message.delete_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
|
||||
mme_s11_handle_release_access_bearers_response(
|
||||
xact, mme_ue, >p_message.release_access_bearers_response);
|
||||
xact, sgw_ue, >p_message.release_access_bearers_response);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE:
|
||||
if (!mme_ue) {
|
||||
if (gtp_message.h.teid_presence)
|
||||
ogs_warn("No Context : TEID[%d]", gtp_message.h.teid);
|
||||
else
|
||||
ogs_warn("No Context : No TEID");
|
||||
|
||||
break;
|
||||
}
|
||||
mme_s11_handle_downlink_data_notification(
|
||||
xact, mme_ue, >p_message.downlink_data_notification);
|
||||
xact, sgw_ue, >p_message.downlink_data_notification);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
|
||||
mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
||||
xact, mme_ue,
|
||||
xact, sgw_ue,
|
||||
>p_message.create_indirect_data_forwarding_tunnel_response);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
|
||||
mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
||||
xact, mme_ue,
|
||||
xact, sgw_ue,
|
||||
>p_message.delete_indirect_data_forwarding_tunnel_response);
|
||||
break;
|
||||
case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE:
|
||||
mme_s11_handle_bearer_resource_failure_indication(
|
||||
xact, mme_ue,
|
||||
xact, sgw_ue,
|
||||
>p_message.bearer_resource_failure_indication);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -55,6 +55,9 @@ static mme_timer_cfg_t g_mme_timer_cfg[MAX_NUM_OF_MME_TIMER] = {
|
|||
|
||||
[MME_TIMER_S1_HOLDING] =
|
||||
{ .duration = ogs_time_from_sec(30) },
|
||||
|
||||
[MME_TIMER_S11_HOLDING] =
|
||||
{ .duration = ogs_time_from_msec(300) },
|
||||
};
|
||||
|
||||
static void emm_timer_event_send(
|
||||
|
@ -89,6 +92,8 @@ const char *mme_timer_get_name(mme_timer_e id)
|
|||
return "MME_TIMER_SGS_CLI_CONN_TO_SRV";
|
||||
case MME_TIMER_S1_HOLDING:
|
||||
return "MME_TIMER_S1_HOLDING";
|
||||
case MME_TIMER_S11_HOLDING:
|
||||
return "MME_TIMER_S11_HOLDING";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -216,3 +221,24 @@ void mme_timer_s1_holding_timer_expire(void *data)
|
|||
mme_event_free(e);
|
||||
}
|
||||
}
|
||||
|
||||
void mme_timer_s11_holding_timer_expire(void *data)
|
||||
{
|
||||
int rv;
|
||||
mme_event_t *e = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(data);
|
||||
sgw_ue = data;
|
||||
|
||||
e = mme_event_new(MME_EVT_S11_TIMER);
|
||||
|
||||
e->timer_id = MME_TIMER_S11_HOLDING;
|
||||
e->sgw_ue = sgw_ue;
|
||||
|
||||
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
|
||||
mme_event_free(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ typedef enum {
|
|||
MME_TIMER_T3470,
|
||||
MME_TIMER_T3489,
|
||||
|
||||
MME_TIMER_S11_HOLDING,
|
||||
|
||||
MME_TIMER_SGS_CLI_CONN_TO_SRV,
|
||||
|
||||
MAX_NUM_OF_MME_TIMER,
|
||||
|
@ -66,6 +68,7 @@ void mme_timer_t3489_expire(void *data);
|
|||
|
||||
void mme_timer_sgs_cli_conn_to_srv(void *data);
|
||||
void mme_timer_s1_holding_timer_expire(void *data);
|
||||
void mme_timer_s11_holding_timer_expire(void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
|||
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
||||
S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE, 0));
|
||||
}
|
||||
mme_ue_associate_enb_ue(mme_ue, enb_ue);
|
||||
enb_ue_associate_mme_ue(enb_ue, mme_ue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -690,6 +690,10 @@ void s1ap_handle_initial_context_setup_response(
|
|||
ogs_expect_or_return(mme_ue);
|
||||
|
||||
if (E_RABSetupListCtxtSURes) {
|
||||
int uli_presence = 0;
|
||||
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
|
||||
for (i = 0; i < E_RABSetupListCtxtSURes->list.count; i++) {
|
||||
S1AP_E_RABSetupItemCtxtSUResIEs_t *item = NULL;
|
||||
S1AP_E_RABSetupItemCtxtSURes_t *e_rab = NULL;
|
||||
|
@ -745,15 +749,19 @@ void s1ap_handle_initial_context_setup_response(
|
|||
|
||||
if (OGS_FSM_CHECK(&bearer->sm, esm_state_active)) {
|
||||
ogs_debug(" NAS_EPS Type[%d]", mme_ue->nas_eps.type);
|
||||
int uli_presence = 0;
|
||||
if (mme_ue->nas_eps.type != MME_EPS_TYPE_ATTACH_REQUEST) {
|
||||
ogs_debug(" ### ULI PRESENT ###");
|
||||
uli_presence = 1;
|
||||
}
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(bearer, uli_presence));
|
||||
ogs_list_add(&mme_ue->bearer_to_modify_list,
|
||||
&bearer->to_modify_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (ogs_list_count(&mme_ue->bearer_to_modify_list)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(mme_ue, uli_presence, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (mme_ue->nas_eps.type != MME_EPS_TYPE_ATTACH_REQUEST)
|
||||
|
@ -1213,12 +1221,15 @@ void s1ap_handle_e_rab_setup_response(
|
|||
ogs_debug(" Linked-EBI[%d]", linked_bearer->ebi);
|
||||
|
||||
if (bearer->ebi == linked_bearer->ebi) {
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(bearer, 0));
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
ogs_list_add(&mme_ue->bearer_to_modify_list,
|
||||
&bearer->to_modify_node);
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(mme_ue, 0, 0));
|
||||
} else {
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_create_bearer_response(
|
||||
bearer, OGS_GTP2_CAUSE_REQUEST_ACCEPTED));
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_create_bearer_response(
|
||||
bearer, OGS_GTP2_CAUSE_REQUEST_ACCEPTED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1471,7 +1482,7 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
|
|||
ogs_debug(" Action: S1 normal release");
|
||||
enb_ue_remove(enb_ue);
|
||||
ogs_expect_or_return(mme_ue);
|
||||
mme_ue_deassociate(mme_ue);
|
||||
enb_ue_unlink(mme_ue);
|
||||
break;
|
||||
case S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE:
|
||||
ogs_debug(" Action: UE context remove");
|
||||
|
@ -1484,7 +1495,7 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
|
|||
case S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE:
|
||||
ogs_debug(" Action: S1 handover complete");
|
||||
|
||||
source_ue_deassociate_target_ue(enb_ue);
|
||||
enb_ue_source_deassociate_target(enb_ue);
|
||||
enb_ue_remove(enb_ue);
|
||||
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
@ -1502,7 +1513,7 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
|
|||
case S1AP_UE_CTX_REL_S1_HANDOVER_CANCEL:
|
||||
ogs_warn(" Action: S1 handover cancel");
|
||||
|
||||
source_ue_deassociate_target_ue(enb_ue);
|
||||
enb_ue_source_deassociate_target(enb_ue);
|
||||
enb_ue_remove(enb_ue);
|
||||
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
@ -1524,7 +1535,7 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
|
|||
case S1AP_UE_CTX_REL_S1_HANDOVER_FAILURE:
|
||||
ogs_warn(" Action: S1 handover failure");
|
||||
|
||||
source_ue_deassociate_target_ue(enb_ue);
|
||||
enb_ue_source_deassociate_target(enb_ue);
|
||||
enb_ue_remove(enb_ue);
|
||||
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
@ -1538,7 +1549,7 @@ void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue)
|
|||
ogs_debug(" Action: S1 paging");
|
||||
enb_ue_remove(enb_ue);
|
||||
ogs_expect_or_return(mme_ue);
|
||||
mme_ue_deassociate(mme_ue);
|
||||
enb_ue_unlink(mme_ue);
|
||||
|
||||
ogs_assert(OGS_OK == s1ap_send_paging(mme_ue, S1AP_CNDomain_ps));
|
||||
break;
|
||||
|
@ -1639,6 +1650,8 @@ void s1ap_handle_e_rab_modification_indication(
|
|||
mme_ue = enb_ue->mme_ue;
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
|
||||
for (i = 0; i < E_RABToBeModifiedListBearerModInd->list.count; i++) {
|
||||
S1AP_E_RABToBeModifiedItemBearerModIndIEs_t *item = NULL;
|
||||
S1AP_E_RABToBeModifiedItemBearerModInd_t *e_rab = NULL;
|
||||
|
@ -1689,11 +1702,12 @@ void s1ap_handle_e_rab_modification_indication(
|
|||
return;
|
||||
}
|
||||
|
||||
GTP_COUNTER_INCREMENT(
|
||||
mme_ue, GTP_COUNTER_MODIFY_BEARER_BY_E_RAB_MODIFICATION);
|
||||
ogs_list_add(&mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
}
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(bearer, 0));
|
||||
if (ogs_list_count(&mme_ue->bearer_to_modify_list)) {
|
||||
ogs_assert(OGS_OK == mme_gtp_send_modify_bearer_request(
|
||||
mme_ue, 0, OGS_GTP_MODIFY_IN_E_RAB_MODIFICATION));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1727,6 +1741,8 @@ void s1ap_handle_path_switch_request(
|
|||
mme_ue_t *mme_ue = NULL;
|
||||
ogs_pkbuf_t *s1apbuf = NULL;
|
||||
|
||||
sgw_relocation_e relocation;
|
||||
|
||||
ogs_assert(enb);
|
||||
ogs_assert(enb->sctp.sock);
|
||||
|
||||
|
@ -1839,6 +1855,17 @@ void s1ap_handle_path_switch_request(
|
|||
mme_ue = enb_ue->mme_ue;
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
||||
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
||||
ogs_error("No Security Context");
|
||||
s1apbuf = s1ap_build_path_switch_failure(
|
||||
*ENB_UE_S1AP_ID, *MME_UE_S1AP_ID,
|
||||
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure);
|
||||
ogs_expect_or_return(s1apbuf);
|
||||
|
||||
s1ap_send_to_enb_ue(enb_ue, s1apbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
ogs_info(" OLD TAI[PLMN_ID:%06x,TAC:%d]",
|
||||
ogs_plmn_id_hexdump(&mme_ue->tai.plmn_id),
|
||||
mme_ue->tai.tac);
|
||||
|
@ -1896,77 +1923,89 @@ void s1ap_handle_path_switch_request(
|
|||
mme_ue->ue_network_capability.eia = eia >> 9;
|
||||
mme_ue->ue_network_capability.eia0 = eia0;
|
||||
|
||||
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
||||
ogs_error("No Security Context");
|
||||
s1apbuf = s1ap_build_path_switch_failure(
|
||||
*ENB_UE_S1AP_ID, *MME_UE_S1AP_ID,
|
||||
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure);
|
||||
ogs_expect_or_return(s1apbuf);
|
||||
|
||||
s1ap_send_to_enb_ue(enb_ue, s1apbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update Security Context (NextHop) */
|
||||
mme_ue->nhcc++;
|
||||
ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->nh, mme_ue->nh);
|
||||
|
||||
for (i = 0; i < E_RABToBeSwitchedDLList->list.count; i++) {
|
||||
S1AP_E_RABToBeSwitchedDLItemIEs_t *item = NULL;
|
||||
S1AP_E_RABToBeSwitchedDLItem_t *e_rab = NULL;
|
||||
#if 0
|
||||
relocation = sgw_ue_check_if_relocated(mme_ue);
|
||||
#else
|
||||
relocation = SGW_WITHOUT_RELOCATION;
|
||||
#endif
|
||||
if (relocation == SGW_WITHOUT_RELOCATION) {
|
||||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
|
||||
item = (S1AP_E_RABToBeSwitchedDLItemIEs_t *)
|
||||
E_RABToBeSwitchedDLList->list.array[i];
|
||||
if (!item) {
|
||||
ogs_error("No S1AP_E_RABToBeSwitchedDLItemIEs_t");
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
for (i = 0; i < E_RABToBeSwitchedDLList->list.count; i++) {
|
||||
S1AP_E_RABToBeSwitchedDLItemIEs_t *item = NULL;
|
||||
S1AP_E_RABToBeSwitchedDLItem_t *e_rab = NULL;
|
||||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
|
||||
item = (S1AP_E_RABToBeSwitchedDLItemIEs_t *)
|
||||
E_RABToBeSwitchedDLList->list.array[i];
|
||||
if (!item) {
|
||||
ogs_error("No S1AP_E_RABToBeSwitchedDLItemIEs_t");
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
}
|
||||
|
||||
e_rab = &item->value.choice.E_RABToBeSwitchedDLItem;
|
||||
if (!e_rab) {
|
||||
ogs_error("No E_RABToBeSwitchedDLItem");
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
}
|
||||
|
||||
bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID);
|
||||
if (!bearer) {
|
||||
ogs_error("No Bearer [%d]", (int)e_rab->e_RAB_ID);
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_radioNetwork,
|
||||
S1AP_CauseRadioNetwork_unknown_E_RAB_ID));
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
||||
sizeof(bearer->enb_s1u_teid));
|
||||
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
||||
rv = ogs_asn_BIT_STRING_to_ip(
|
||||
&e_rab->transportLayerAddress, &bearer->enb_s1u_ip);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("No transportLayerAddress [%d]",
|
||||
(int)e_rab->e_RAB_ID);
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_protocol,
|
||||
S1AP_CauseProtocol_abstract_syntax_error_falsely_constructed_message));
|
||||
return;
|
||||
}
|
||||
|
||||
ogs_list_add(
|
||||
&mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
}
|
||||
|
||||
e_rab = &item->value.choice.E_RABToBeSwitchedDLItem;
|
||||
if (!e_rab) {
|
||||
ogs_error("No E_RABToBeSwitchedDLItem");
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error));
|
||||
return;
|
||||
if (ogs_list_count(&mme_ue->bearer_to_modify_list)) {
|
||||
ogs_assert(OGS_OK == mme_gtp_send_modify_bearer_request(
|
||||
mme_ue, 1, OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST));
|
||||
}
|
||||
} else if (relocation == SGW_WITH_RELOCATION) {
|
||||
mme_sess_t *sess = NULL;
|
||||
|
||||
bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID);
|
||||
if (!bearer) {
|
||||
ogs_error("No Bearer [%d]", (int)e_rab->e_RAB_ID);
|
||||
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_radioNetwork,
|
||||
S1AP_CauseRadioNetwork_unknown_E_RAB_ID));
|
||||
return;
|
||||
mme_gtp_send_create_session_request(
|
||||
sess, OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST));
|
||||
}
|
||||
|
||||
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
||||
sizeof(bearer->enb_s1u_teid));
|
||||
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
||||
rv = ogs_asn_BIT_STRING_to_ip(
|
||||
&e_rab->transportLayerAddress, &bearer->enb_s1u_ip);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_error("No transportLayerAddress [%d]",
|
||||
(int)e_rab->e_RAB_ID);
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_error_indication2(mme_ue,
|
||||
S1AP_Cause_PR_protocol,
|
||||
S1AP_CauseProtocol_abstract_syntax_error_falsely_constructed_message));
|
||||
return;
|
||||
}
|
||||
|
||||
GTP_COUNTER_INCREMENT(
|
||||
mme_ue, GTP_COUNTER_MODIFY_BEARER_BY_PATH_SWITCH);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(bearer, 1));
|
||||
} else if (relocation == SGW_HAS_ALREADY_BEEN_RELOCATED) {
|
||||
ogs_error("SGW has already been relocated");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void s1ap_handle_enb_configuration_transfer(
|
||||
|
@ -2211,18 +2250,19 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
|||
mme_ue = source_ue->mme_ue;
|
||||
ogs_expect_or_return(mme_ue);
|
||||
|
||||
source_ue->handover_type = *HandoverType;
|
||||
|
||||
if (SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
||||
mme_ue->nhcc++;
|
||||
ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->nh, mme_ue->nh);
|
||||
} else {
|
||||
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
|
||||
ogs_error("No Security Context");
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_handover_preparation_failure(source_ue,
|
||||
S1AP_Cause_PR_nas, S1AP_CauseNas_authentication_failure));
|
||||
return;
|
||||
}
|
||||
|
||||
source_ue->handover_type = *HandoverType;
|
||||
|
||||
mme_ue->nhcc++;
|
||||
ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->nh, mme_ue->nh);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
s1ap_send_handover_request(
|
||||
source_ue, target_enb, HandoverType, Cause,
|
||||
|
@ -2876,7 +2916,7 @@ void s1ap_handle_handover_notification(
|
|||
ogs_debug(" Target : ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
|
||||
target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id);
|
||||
|
||||
mme_ue_associate_enb_ue(mme_ue, target_ue);
|
||||
enb_ue_associate_mme_ue(target_ue, mme_ue);
|
||||
|
||||
memcpy(&target_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
||||
sizeof(target_ue->saved.tai.plmn_id));
|
||||
|
@ -2916,16 +2956,23 @@ void s1ap_handle_handover_notification(
|
|||
S1AP_UE_CTX_REL_S1_HANDOVER_COMPLETE,
|
||||
ogs_app()->time.handover.duration));
|
||||
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
|
||||
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
bearer->enb_s1u_teid = bearer->target_s1u_teid;
|
||||
memcpy(&bearer->enb_s1u_ip, &bearer->target_s1u_ip,
|
||||
sizeof(ogs_ip_t));
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_modify_bearer_request(bearer, 1));
|
||||
ogs_list_add(
|
||||
&mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ogs_list_count(&mme_ue->bearer_to_modify_list)) {
|
||||
ogs_assert(OGS_OK == mme_gtp_send_modify_bearer_request(mme_ue, 1, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void s1ap_handle_s1_reset(
|
||||
|
|
|
@ -510,7 +510,7 @@ int s1ap_send_handover_request(
|
|||
ogs_info(" Target : ENB_UE_S1AP_ID[Unknown] MME_UE_S1AP_ID[%d]",
|
||||
target_ue->mme_ue_s1ap_id);
|
||||
|
||||
source_ue_associate_target_ue(source_ue, target_ue);
|
||||
enb_ue_source_associate_target(source_ue, target_ue);
|
||||
|
||||
s1apbuf = s1ap_build_handover_request(
|
||||
target_ue, handovertype, cause,
|
||||
|
|
|
@ -473,6 +473,32 @@ sgwc_sess_t *sgwc_sess_cycle(sgwc_sess_t *sess)
|
|||
return ogs_pool_cycle(&sgwc_sess_pool, sess);
|
||||
}
|
||||
|
||||
int sgwc_sess_pfcp_xact_count(
|
||||
sgwc_ue_t *sgwc_ue, uint8_t pfcp_type, uint64_t modify_flags)
|
||||
{
|
||||
sgwc_sess_t *sess = NULL;
|
||||
int xact_count = 0;
|
||||
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
ogs_pfcp_node_t *pfcp_node = sess->pfcp_node;
|
||||
ogs_pfcp_xact_t *pfcp_xact = NULL;
|
||||
ogs_assert(pfcp_node);
|
||||
ogs_list_for_each(&pfcp_node->local_list, pfcp_xact) {
|
||||
if (sess != pfcp_xact->data)
|
||||
continue;
|
||||
if (pfcp_type && pfcp_type != pfcp_xact->seq[0].type)
|
||||
continue;
|
||||
if (modify_flags && modify_flags != pfcp_xact->modify_flags)
|
||||
continue;
|
||||
xact_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return xact_count;
|
||||
}
|
||||
|
||||
sgwc_bearer_t *sgwc_bearer_add(sgwc_sess_t *sess)
|
||||
{
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
|
|
@ -81,19 +81,6 @@ typedef struct sgwc_sess_s {
|
|||
uint64_t sgwc_sxa_seid; /* SGW-C SEID is dervied from INDEX */
|
||||
uint64_t sgwu_sxa_seid; /* SGW-U SEID is received from Peer */
|
||||
|
||||
/*
|
||||
* PFCP modification request is set to FALSE
|
||||
* PFCP modifitation response is set to TRUE
|
||||
*
|
||||
* For example, when SGW-C is received Release Access Bearers Request,
|
||||
* it is used to check if all sessions are deactivated.
|
||||
*/
|
||||
struct {
|
||||
bool release_access_bearers;
|
||||
bool create_indirect_tunnel;
|
||||
bool delete_indirect_tunnel;
|
||||
} state;
|
||||
|
||||
/* APN Configuration */
|
||||
ogs_session_t session;
|
||||
|
||||
|
@ -108,6 +95,7 @@ typedef struct sgwc_sess_s {
|
|||
|
||||
typedef struct sgwc_bearer_s {
|
||||
ogs_lnode_t lnode;
|
||||
ogs_lnode_t to_modify_node;
|
||||
|
||||
uint8_t ebi;
|
||||
|
||||
|
@ -167,6 +155,11 @@ sgwc_sess_t *sgwc_sess_find_by_apn(sgwc_ue_t *sgwc_ue, char *apn);
|
|||
sgwc_sess_t *sgwc_sess_find_by_ebi(sgwc_ue_t *sgwc_ue, uint8_t ebi);
|
||||
sgwc_sess_t *sgwc_sess_cycle(sgwc_sess_t *sess);
|
||||
|
||||
#define SESSION_SYNC_DONE(__sGWC, __tYPE, __fLAGS) \
|
||||
(sgwc_sess_pfcp_xact_count(__sGWC, __tYPE, __fLAGS) == 0)
|
||||
int sgwc_sess_pfcp_xact_count(
|
||||
sgwc_ue_t *sgwc_ue, uint8_t pfcp_type, uint64_t modify_flags);
|
||||
|
||||
sgwc_bearer_t *sgwc_bearer_add(sgwc_sess_t *sess);
|
||||
int sgwc_bearer_remove(sgwc_bearer_t *bearer);
|
||||
void sgwc_bearer_remove_all(sgwc_sess_t *sess);
|
||||
|
|
|
@ -216,18 +216,69 @@ int sgwc_pfcp_send_session_establishment_request(
|
|||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
sxabuf = sgwc_sxa_build_session_establishment_request(h.type, sess);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, sxabuf, sess_timeout, sess);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_xact = gtp_xact;
|
||||
if (gtpbuf) {
|
||||
xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
||||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
sxabuf = sgwc_sxa_build_session_establishment_request(h.type, sess);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
ogs_pfcp_xact_t *sgwc_pfcp_xact_create(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact,
|
||||
ogs_pkbuf_t *gtpbuf, uint64_t flags)
|
||||
{
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, NULL);
|
||||
|
||||
xact->assoc_xact = gtp_xact;
|
||||
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
|
||||
if (gtpbuf) {
|
||||
xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
||||
ogs_expect_or_return_val(xact->gtpbuf, NULL);
|
||||
}
|
||||
|
||||
return xact;
|
||||
}
|
||||
|
||||
int sgwc_pfcp_xact_commit(ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
int rv;
|
||||
sgwc_sess_t *sess = NULL;
|
||||
ogs_pkbuf_t *sxabuf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
|
||||
ogs_assert(xact);
|
||||
sess = xact->data;
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
sxabuf = sgwc_sxa_build_session_modification_request(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
|
@ -238,39 +289,18 @@ int sgwc_pfcp_send_sess_modification_request(
|
|||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact,
|
||||
ogs_pkbuf_t *gtpbuf, uint64_t flags)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *sxabuf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
sxabuf = sgwc_sxa_build_sess_modification_request(
|
||||
h.type, sess, flags, &pdr_to_create_list);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, sxabuf, sess_timeout, sess);
|
||||
xact = sgwc_pfcp_xact_create(sess, gtp_xact, gtpbuf, flags);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->assoc_xact = gtp_xact;
|
||||
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
|
||||
if (gtpbuf) {
|
||||
xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
||||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list);
|
||||
ogs_list_for_each(&sess->bearer_list, bearer)
|
||||
ogs_list_add(&xact->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
return sgwc_pfcp_xact_commit(xact);
|
||||
}
|
||||
|
||||
int sgwc_pfcp_send_bearer_modification_request(
|
||||
|
@ -283,23 +313,13 @@ int sgwc_pfcp_send_bearer_modification_request(
|
|||
ogs_pfcp_xact_t *xact = NULL;
|
||||
sgwc_sess_t *sess = NULL;
|
||||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
sxabuf = sgwc_sxa_build_bearer_modification_request(
|
||||
h.type, bearer, flags, &pdr_to_create_list);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, sxabuf, bearer_timeout, bearer);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, bearer_timeout, bearer);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_xact = gtp_xact;
|
||||
xact->modify_flags = flags;
|
||||
if (gtpbuf) {
|
||||
|
@ -307,7 +327,17 @@ int sgwc_pfcp_send_bearer_modification_request(
|
|||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list);
|
||||
ogs_list_add(&xact->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
sxabuf = sgwc_sxa_build_session_modification_request(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -329,18 +359,21 @@ int sgwc_pfcp_send_session_deletion_request(
|
|||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
sxabuf = sgwc_sxa_build_session_deletion_request(h.type, sess);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, sxabuf, sess_timeout, sess);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_xact = gtp_xact;
|
||||
if (gtpbuf) {
|
||||
xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
||||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
sxabuf = sgwc_sxa_build_session_deletion_request(h.type, sess);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
|
|
|
@ -31,9 +31,26 @@ void sgwc_pfcp_close(void);
|
|||
|
||||
int sgwc_pfcp_send_session_establishment_request(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact, ogs_pkbuf_t *gtpbuf);
|
||||
|
||||
/*
|
||||
* sgwc_pfcp_xact_create()/sgwc_pfcp_xact_commit() can only be used
|
||||
* with sgwc_pfcp_send_sess_modification_request()
|
||||
*
|
||||
* You should not use the following functions
|
||||
* - sgwc_pfcp_send_session_establishment_request()
|
||||
* - sgwc_pfcp_send_bearer_modification_request()
|
||||
* - sgwc_pfcp_send_session_deletion_request()
|
||||
* - sgwc_pfcp_send_session_report_response()
|
||||
*/
|
||||
ogs_pfcp_xact_t *sgwc_pfcp_xact_create(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact,
|
||||
ogs_pkbuf_t *gtpbuf, uint64_t flags);
|
||||
int sgwc_pfcp_xact_commit(ogs_pfcp_xact_t *xact);
|
||||
|
||||
int sgwc_pfcp_send_sess_modification_request(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact,
|
||||
ogs_pkbuf_t *gtpbuf, uint64_t flags);
|
||||
|
||||
int sgwc_pfcp_send_bearer_modification_request(
|
||||
sgwc_bearer_t *bearer, ogs_gtp_xact_t *gtp_xact,
|
||||
ogs_pkbuf_t *gtpbuf, uint64_t flags);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,8 @@ static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
|
||||
ogs_error("[%s] No Delete Bearer Response", sgwc_ue->imsi_bcd);
|
||||
if (!sgwc_bearer_cycle(bearer)) {
|
||||
ogs_warn("[%s] Bearer has already been removed", sgwc_ue->imsi_bcd);
|
||||
ogs_error("[%s] Bearer has already been removed",
|
||||
sgwc_ue->imsi_bcd);
|
||||
break;
|
||||
}
|
||||
ogs_assert(OGS_OK ==
|
||||
|
@ -63,9 +64,8 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||
{
|
||||
int rv;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
ogs_gtp2_cause_t *bearer_cause = NULL;
|
||||
uint8_t cause_value;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
@ -78,9 +78,6 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_gtp2_create_session_response_t *rsp = NULL;
|
||||
ogs_gtp_xact_t *s11_xact = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
ogs_assert(gtpbuf);
|
||||
ogs_assert(message);
|
||||
rsp = &message->create_session_response;
|
||||
|
@ -88,25 +85,38 @@ void sgwc_s5c_handle_create_session_response(
|
|||
|
||||
ogs_debug("Create Session Response");
|
||||
|
||||
/***************************
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
***************************/
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context in TEID");
|
||||
sess = s5c_xact->data;
|
||||
ogs_assert(sess);
|
||||
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
if (rsp->bearer_contexts_created.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
||||
rsp->bearer_contexts_created.eps_bearer_id.u8);
|
||||
if (!bearer) {
|
||||
|
@ -117,9 +127,6 @@ void sgwc_s5c_handle_create_session_response(
|
|||
}
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
|
@ -127,24 +134,11 @@ void sgwc_s5c_handle_create_session_response(
|
|||
return;
|
||||
}
|
||||
|
||||
/***************************
|
||||
* Check Manatory IE Missing
|
||||
***************************/
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->bearer_contexts_created.cause.presence == 0) {
|
||||
ogs_error("No EPS Bearer Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence == 0) {
|
||||
ogs_error("No GTP TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
|
@ -153,31 +147,15 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_error("No GTP TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (rsp->bearer_contexts_created.cause.presence == 0) {
|
||||
ogs_error("No Bearer Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (rsp->pdn_address_allocation.presence) {
|
||||
ogs_paa_t paa;
|
||||
|
||||
memcpy(&paa, rsp->pdn_address_allocation.data,
|
||||
ogs_min(sizeof(paa), rsp->pdn_address_allocation.len));
|
||||
if (paa.session_type == OGS_PDU_SESSION_TYPE_IPV4) {
|
||||
/* Nothing */
|
||||
} else if (paa.session_type == OGS_PDU_SESSION_TYPE_IPV6) {
|
||||
/* Nothing */
|
||||
} else if (paa.session_type == OGS_PDU_SESSION_TYPE_IPV4V6) {
|
||||
/* Nothing */
|
||||
} else {
|
||||
|
||||
if (!OGS_PDU_SESSION_TYPE_IS_VALID(paa.session_type)) {
|
||||
ogs_error("Unknown PDN Type %u", paa.session_type);
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -185,6 +163,15 @@ void sgwc_s5c_handle_create_session_response(
|
|||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.cause.presence == 0) {
|
||||
ogs_error("No Bearer Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
|
@ -192,14 +179,14 @@ void sgwc_s5c_handle_create_session_response(
|
|||
return;
|
||||
}
|
||||
|
||||
/***************************
|
||||
/********************
|
||||
* Check Cause Value
|
||||
***************************/
|
||||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
bearer_cause = rsp->bearer_contexts_created.cause.data;
|
||||
ogs_assert(bearer_cause);
|
||||
cause_value = bearer_cause->value;
|
||||
cause = rsp->bearer_contexts_created.cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
|
@ -224,6 +211,11 @@ void sgwc_s5c_handle_create_session_response(
|
|||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(sess);
|
||||
ogs_assert(bearer);
|
||||
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
||||
ogs_assert(ul_tunnel);
|
||||
|
@ -275,6 +267,7 @@ void sgwc_s5c_handle_delete_session_response(
|
|||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||
{
|
||||
int rv;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
uint8_t cause_value;
|
||||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
@ -282,43 +275,81 @@ void sgwc_s5c_handle_delete_session_response(
|
|||
ogs_gtp_xact_t *s11_xact = NULL;
|
||||
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
ogs_assert(message);
|
||||
rsp = &message->delete_session_response;
|
||||
ogs_assert(rsp);
|
||||
|
||||
ogs_debug("Delete Session Response");
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context in TEID");
|
||||
sess = s5c_xact->data;
|
||||
ogs_assert(sess);
|
||||
}
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sess);
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
/* Remove a pgw session */
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
||||
|
@ -338,6 +369,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||
{
|
||||
int rv;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
uint8_t cause_value;
|
||||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
@ -346,35 +378,48 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
ogs_gtp_xact_t *s11_xact = NULL;
|
||||
ogs_gtp2_modify_bearer_response_t *rsp = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
ogs_assert(message);
|
||||
rsp = &message->modify_bearer_response;
|
||||
ogs_assert(rsp);
|
||||
|
||||
ogs_debug("Modify Bearer Response");
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context in TEID");
|
||||
sess = s5c_xact->data;
|
||||
ogs_assert(sess);
|
||||
}
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
@ -386,6 +431,28 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(sess);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
|
@ -419,15 +486,41 @@ void sgwc_s5c_handle_create_bearer_request(
|
|||
ogs_gtp2_create_bearer_request_t *req = NULL;
|
||||
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
ogs_assert(message);
|
||||
req = &message->create_bearer_request;
|
||||
ogs_assert(req);
|
||||
|
||||
ogs_debug("Create Bearer Request");
|
||||
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (req->linked_eps_bearer_id.presence == 0) {
|
||||
ogs_error("No Linked EBI");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
@ -442,12 +535,7 @@ void sgwc_s5c_handle_create_bearer_request(
|
|||
}
|
||||
if (req->bearer_contexts.s4_u_sgsn_f_teid.presence == 0) {
|
||||
ogs_error("No GTP TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -456,7 +544,10 @@ void sgwc_s5c_handle_create_bearer_request(
|
|||
return;
|
||||
}
|
||||
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sess);
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
bearer = sgwc_bearer_add(sess);
|
||||
|
@ -512,39 +603,47 @@ void sgwc_s5c_handle_update_bearer_request(
|
|||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
ogs_assert(message);
|
||||
req = &message->update_bearer_request;
|
||||
ogs_assert(req);
|
||||
|
||||
ogs_debug("Update Bearer Request");
|
||||
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (req->bearer_contexts.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context");
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
bearer = sgwc_bearer_find_by_sess_ebi(
|
||||
sess, req->bearer_contexts.eps_bearer_id.u8);
|
||||
if (!bearer)
|
||||
ogs_error("No Context for EPS Bearer ID[%d]",
|
||||
if (req->bearer_contexts.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
||||
req->bearer_contexts.eps_bearer_id.u8);
|
||||
}
|
||||
if (!bearer) {
|
||||
ogs_warn("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
if (!bearer) {
|
||||
ogs_error("No Context for EPS Bearer ID[%d]",
|
||||
req->bearer_contexts.eps_bearer_id.u8);
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -553,9 +652,11 @@ void sgwc_s5c_handle_update_bearer_request(
|
|||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sess);
|
||||
ogs_assert(bearer);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(sgwc_ue->gnode);
|
||||
|
||||
|
@ -601,66 +702,78 @@ void sgwc_s5c_handle_delete_bearer_request(
|
|||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
ogs_assert(message);
|
||||
req = &message->delete_bearer_request;
|
||||
ogs_assert(req);
|
||||
|
||||
ogs_debug("Delete Bearer Request");
|
||||
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (req->linked_eps_bearer_id.presence == 0 &&
|
||||
req->eps_bearer_ids.presence == 0) {
|
||||
ogs_error("No Linked EBI or EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context");
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
uint8_t ebi;
|
||||
if (req->linked_eps_bearer_id.presence == 0 &&
|
||||
req->eps_bearer_ids.presence == 0) {
|
||||
ogs_error("No Linked EBI or EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (req->linked_eps_bearer_id.presence) {
|
||||
/*
|
||||
* << Linked EPS Bearer ID >>
|
||||
*
|
||||
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
|
||||
* 2. MME sends Delete Bearer Response to SGW/SMF.
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
|
||||
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
|
||||
*/
|
||||
ebi = req->linked_eps_bearer_id.u8;
|
||||
} else if (req->eps_bearer_ids.presence) {
|
||||
/*
|
||||
* << EPS Bearer IDs >>
|
||||
*
|
||||
* 1. MME sends Bearer Resource Command to SGW/SMF.
|
||||
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
||||
* 3. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
||||
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
||||
*/
|
||||
ebi = req->eps_bearer_ids.u8;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
uint8_t ebi;
|
||||
|
||||
bearer = sgwc_bearer_find_by_sess_ebi(sess, ebi);
|
||||
if (!bearer)
|
||||
ogs_error("No Context for EPS Bearer ID[%d]", ebi);
|
||||
}
|
||||
if (!bearer) {
|
||||
ogs_warn("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
if (req->linked_eps_bearer_id.presence) {
|
||||
/*
|
||||
* << Linked EPS Bearer ID >>
|
||||
*
|
||||
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
|
||||
* 2. MME sends Delete Bearer Response to SGW/SMF.
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
|
||||
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
|
||||
*/
|
||||
ebi = req->linked_eps_bearer_id.u8;
|
||||
} else if (req->eps_bearer_ids.presence) {
|
||||
/*
|
||||
* << EPS Bearer IDs >>
|
||||
*
|
||||
* 1. MME sends Bearer Resource Command to SGW/SMF.
|
||||
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER)
|
||||
* to SGW/MME.
|
||||
* 3. MME sends Delete Bearer Response(DEDICATED BEARER)
|
||||
* to SGW/SMF.
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER)
|
||||
* to SGW/MME.
|
||||
* 2. MME sends Delete Bearer Response(DEDICATED BEARER)
|
||||
* to SGW/SMF.
|
||||
*/
|
||||
ebi = req->eps_bearer_ids.u8;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
bearer = sgwc_bearer_find_by_sess_ebi(sess, ebi);
|
||||
if (!bearer) {
|
||||
ogs_error("No Context for EPS Bearer ID[%d]", ebi);
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -669,9 +782,11 @@ void sgwc_s5c_handle_delete_bearer_request(
|
|||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sess);
|
||||
ogs_assert(bearer);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(sgwc_ue->gnode);
|
||||
|
||||
|
@ -732,23 +847,33 @@ void sgwc_s5c_handle_bearer_resource_failure_indication(
|
|||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
ogs_assert(message);
|
||||
ind = &message->bearer_resource_failure_indication;
|
||||
ogs_assert(ind);
|
||||
|
||||
ogs_debug("Bearer Resource Failure Indication");
|
||||
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
if (!sess) {
|
||||
ogs_warn("No Context");
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
********************/
|
||||
if (ind->cause.presence) {
|
||||
ogs_gtp2_cause_t *cause = ind->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
|
|
@ -105,17 +105,17 @@ ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request(
|
|||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request(
|
||||
uint8_t type, sgwc_sess_t *sess, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list)
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
||||
uint8_t type, sgwc_sess_t *sess, ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_modification_request_t *req = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
sgwc_tunnel_t *tunnel = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
||||
int num_of_remove_pdr = 0;
|
||||
int num_of_remove_far = 0;
|
||||
|
@ -123,18 +123,30 @@ ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request(
|
|||
int num_of_create_far = 0;
|
||||
int num_of_update_far = 0;
|
||||
|
||||
uint64_t modify_flags = 0;
|
||||
|
||||
ogs_debug("Session Modification Request");
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
modify_flags = xact->modify_flags;
|
||||
ogs_assert(modify_flags);
|
||||
|
||||
req = &pfcp_message.pfcp_session_modification_request;
|
||||
memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t));
|
||||
|
||||
num_of_remove_pdr = 0;
|
||||
num_of_remove_far = 0;
|
||||
num_of_create_pdr = 0;
|
||||
num_of_create_far = 0;
|
||||
num_of_update_far = 0;
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
ogs_pfcp_pdrbuf_init();
|
||||
}
|
||||
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_list_for_each_entry(
|
||||
&xact->bearer_to_modify_list, bearer, to_modify_node) {
|
||||
ogs_list_for_each(&bearer->tunnel_list, tunnel) {
|
||||
if (((modify_flags &
|
||||
(OGS_PFCP_MODIFY_DL_ONLY|
|
||||
|
@ -180,136 +192,7 @@ ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request(
|
|||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
} else {
|
||||
if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
pdr = tunnel->pdr;
|
||||
if (pdr) {
|
||||
ogs_pfcp_build_create_pdr(
|
||||
&req->create_pdr[num_of_create_pdr],
|
||||
num_of_create_pdr, pdr);
|
||||
num_of_create_pdr++;
|
||||
|
||||
ogs_assert(pdr_to_create_list);
|
||||
ogs_list_add(pdr_to_create_list,
|
||||
&pdr->to_create_node);
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
far = tunnel->far;
|
||||
if (far) {
|
||||
ogs_pfcp_build_create_far(
|
||||
&req->create_far[num_of_create_far],
|
||||
num_of_create_far, far);
|
||||
|
||||
num_of_create_far++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
far = tunnel->far;
|
||||
if (far) {
|
||||
ogs_pfcp_build_update_far_deactivate(
|
||||
&req->update_far[num_of_update_far],
|
||||
num_of_update_far, far);
|
||||
|
||||
num_of_update_far++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pfcp_message.h.type = type;
|
||||
pkbuf = ogs_pfcp_build_msg(&pfcp_message);
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
ogs_pfcp_pdrbuf_clear();
|
||||
}
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request(
|
||||
uint8_t type, sgwc_bearer_t *bearer, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list)
|
||||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_modification_request_t *req = NULL;
|
||||
sgwc_tunnel_t *tunnel = NULL;
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
int num_of_remove_pdr = 0;
|
||||
int num_of_remove_far = 0;
|
||||
int num_of_create_pdr = 0;
|
||||
int num_of_create_far = 0;
|
||||
int num_of_update_far = 0;
|
||||
|
||||
sgwc_sess_t *sess = NULL;
|
||||
|
||||
ogs_debug("Session Modification Request");
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
ogs_assert(modify_flags);
|
||||
|
||||
req = &pfcp_message.pfcp_session_modification_request;
|
||||
memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t));
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
ogs_pfcp_pdrbuf_init();
|
||||
}
|
||||
|
||||
ogs_list_for_each(&bearer->tunnel_list, tunnel) {
|
||||
if (((modify_flags &
|
||||
(OGS_PFCP_MODIFY_DL_ONLY|
|
||||
OGS_PFCP_MODIFY_UL_ONLY|
|
||||
OGS_PFCP_MODIFY_INDIRECT)) == 0) ||
|
||||
|
||||
((modify_flags & OGS_PFCP_MODIFY_DL_ONLY) &&
|
||||
(tunnel->interface_type == OGS_GTP2_F_TEID_S5_S8_SGW_GTP_U)) ||
|
||||
|
||||
((modify_flags & OGS_PFCP_MODIFY_UL_ONLY) &&
|
||||
(tunnel->interface_type == OGS_GTP2_F_TEID_S1_U_SGW_GTP_U)) ||
|
||||
|
||||
(((modify_flags & OGS_PFCP_MODIFY_INDIRECT) &&
|
||||
((tunnel->interface_type ==
|
||||
OGS_GTP2_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING) ||
|
||||
(tunnel->interface_type ==
|
||||
OGS_GTP2_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING))))) {
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_REMOVE) {
|
||||
pdr = tunnel->pdr;
|
||||
if (pdr) {
|
||||
ogs_pfcp_tlv_remove_pdr_t *message =
|
||||
&req->remove_pdr[num_of_remove_pdr];
|
||||
|
||||
message->presence = 1;
|
||||
message->pdr_id.presence = 1;
|
||||
message->pdr_id.u16 = pdr->id;
|
||||
|
||||
num_of_remove_pdr++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
far = tunnel->far;
|
||||
if (far) {
|
||||
ogs_pfcp_tlv_remove_far_t *message =
|
||||
&req->remove_far[num_of_remove_far];
|
||||
|
||||
message->presence = 1;
|
||||
message->far_id.presence = 1;
|
||||
message->far_id.u32 = far->id;
|
||||
|
||||
num_of_remove_far++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
} else {
|
||||
if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
} else if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
pdr = tunnel->pdr;
|
||||
if (pdr) {
|
||||
ogs_pfcp_build_create_pdr(
|
||||
|
@ -317,8 +200,8 @@ ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request(
|
|||
num_of_create_pdr, pdr);
|
||||
num_of_create_pdr++;
|
||||
|
||||
ogs_assert(pdr_to_create_list);
|
||||
ogs_list_add(pdr_to_create_list, &pdr->to_create_node);
|
||||
ogs_list_add(&xact->pdr_to_create_list,
|
||||
&pdr->to_create_node);
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
|
@ -331,9 +214,17 @@ ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request(
|
|||
num_of_create_far++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
} else if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
far = tunnel->far;
|
||||
if (far) {
|
||||
ogs_pfcp_build_update_far_deactivate(
|
||||
&req->update_far[num_of_update_far],
|
||||
num_of_update_far, far);
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
num_of_update_far++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
} else if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
far = tunnel->far;
|
||||
if (far) {
|
||||
if (modify_flags & OGS_PFCP_MODIFY_END_MARKER) {
|
||||
|
|
|
@ -28,12 +28,8 @@ extern "C" {
|
|||
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request(
|
||||
uint8_t type, sgwc_sess_t *sess);
|
||||
ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request(
|
||||
uint8_t type, sgwc_sess_t *sess, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list);
|
||||
ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request(
|
||||
uint8_t type, sgwc_bearer_t *bearer, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list);
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
||||
uint8_t type, sgwc_sess_t *sess, ogs_pfcp_xact_t *xact);
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_deletion_request(
|
||||
uint8_t type, sgwc_sess_t *sess);
|
||||
|
||||
|
|
|
@ -126,14 +126,15 @@ static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
|
||||
void sgwc_sxa_handle_session_establishment_response(
|
||||
sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
|
||||
ogs_gtp2_message_t *gtp_message,
|
||||
ogs_gtp2_message_t *recv_message,
|
||||
ogs_pfcp_session_establishment_response_t *pfcp_rsp)
|
||||
{
|
||||
int rv, len = 0;
|
||||
int rv;
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
ogs_pfcp_f_seid_t *up_f_seid = NULL;
|
||||
|
||||
int sgw_s5c_len, sgw_s5u_len;
|
||||
ogs_gtp2_f_teid_t sgw_s5c_teid, sgw_s5u_teid;
|
||||
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
||||
|
||||
|
@ -144,17 +145,19 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
sgwc_bearer_t *bearer = NULL;
|
||||
sgwc_tunnel_t *dl_tunnel = NULL;
|
||||
|
||||
ogs_gtp2_create_session_request_t *gtp_req = NULL;
|
||||
ogs_gtp2_create_session_request_t *create_session_request = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
|
||||
ogs_debug("Session Establishment Response");
|
||||
|
||||
ogs_assert(pfcp_xact);
|
||||
ogs_assert(pfcp_rsp);
|
||||
ogs_assert(gtp_message);
|
||||
ogs_assert(recv_message);
|
||||
|
||||
gtp_req = >p_message->create_session_request;
|
||||
ogs_assert(gtp_req);
|
||||
create_session_request = &recv_message->create_session_request;
|
||||
ogs_assert(create_session_request);
|
||||
|
||||
s11_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
@ -270,18 +273,16 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
sgw_s5c_teid.teid = htobe32(sess->sgw_s5c_teid);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
ogs_gtp_self()->gtpc_addr, ogs_gtp_self()->gtpc_addr6,
|
||||
&sgw_s5c_teid, &len);
|
||||
&sgw_s5c_teid, &sgw_s5c_len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
gtp_req->sender_f_teid_for_control_plane.presence = 1;
|
||||
gtp_req->sender_f_teid_for_control_plane.data = &sgw_s5c_teid;
|
||||
gtp_req->sender_f_teid_for_control_plane.len = len;
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
||||
dl_tunnel->local_teid, dl_tunnel->remote_teid);
|
||||
|
||||
pgw_s5c_teid = gtp_req->pgw_s5_s8_address_for_control_plane_or_pmip.data;
|
||||
pgw_s5c_teid = create_session_request->
|
||||
pgw_s5_s8_address_for_control_plane_or_pmip.data;
|
||||
ogs_assert(pgw_s5c_teid);
|
||||
|
||||
pgw = ogs_gtp_node_find_by_f_teid(&sgwc_self()->pgw_s5c_list, pgw_s5c_teid);
|
||||
|
@ -298,32 +299,101 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
/* Setup GTP Node */
|
||||
OGS_SETUP_GTP_NODE(sess, pgw);
|
||||
|
||||
/* Remove PGW-S5C */
|
||||
gtp_req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 0;
|
||||
|
||||
/* Data Plane(DL) : SGW-S5U */
|
||||
memset(&sgw_s5u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s5u_teid.teid = htobe32(dl_tunnel->local_teid);
|
||||
sgw_s5u_teid.interface_type = dl_tunnel->interface_type;
|
||||
ogs_assert(dl_tunnel->local_addr || dl_tunnel->local_addr6);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
dl_tunnel->local_addr, dl_tunnel->local_addr6, &sgw_s5u_teid, &len);
|
||||
dl_tunnel->local_addr, dl_tunnel->local_addr6,
|
||||
&sgw_s5u_teid, &sgw_s5u_len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
gtp_req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.presence = 1;
|
||||
gtp_req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.data =
|
||||
&sgw_s5u_teid;
|
||||
gtp_req->bearer_contexts_to_be_created.s5_s8_u_sgw_f_teid.len = len;
|
||||
|
||||
gtp_message->h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||
gtp_message->h.teid = sess->pgw_s5c_teid;
|
||||
/* Check Indication */
|
||||
if (create_session_request->indication_flags.presence &&
|
||||
create_session_request->indication_flags.data &&
|
||||
create_session_request->indication_flags.len) {
|
||||
indication = create_session_request->indication_flags.data;
|
||||
}
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(gtp_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
if (indication && indication->operation_indication) {
|
||||
ogs_gtp2_message_t send_message;
|
||||
ogs_gtp2_modify_bearer_request_t *modify_bearer_request =
|
||||
&send_message.modify_bearer_request;
|
||||
|
||||
ogs_assert(sess->gnode);
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, >p_message->h, pkbuf, sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
/*
|
||||
* Operation Indication:
|
||||
* This flag shall be set to 1 on the S4/S11 interface
|
||||
* for a TAU/RAU procedure with SGW relocation, Enhanced
|
||||
* SRNS Relocation with SGW relocation, X2-based handovers
|
||||
* with SGW relocation and MME triggered Serving GW relocation
|
||||
*/
|
||||
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
send_message.h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||
send_message.h.teid = sess->pgw_s5c_teid;
|
||||
|
||||
/* Send Control Plane(DL) : SGW-S5C */
|
||||
modify_bearer_request->sender_f_teid_for_control_plane.presence = 1;
|
||||
modify_bearer_request->sender_f_teid_for_control_plane.
|
||||
data = &sgw_s5c_teid;
|
||||
modify_bearer_request->sender_f_teid_for_control_plane.
|
||||
len = sgw_s5c_len;
|
||||
|
||||
/* Bearer Context : EBI */
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].presence = 1;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
eps_bearer_id.presence = 1;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
/* Data Plane(DL) : SGW-S5U */
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
s4_u_sgsn_f_teid.presence = 1;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
s4_u_sgsn_f_teid.data = &sgw_s5u_teid;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
s4_u_sgsn_f_teid.len = sgw_s5u_len;
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
||||
ogs_assert(sess->gnode);
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &send_message.h, pkbuf, sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
} else {
|
||||
/* Create Session Request */
|
||||
recv_message->h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||
|
||||
/* Send Control Plane(DL) : SGW-S5C */
|
||||
create_session_request->sender_f_teid_for_control_plane.presence = 1;
|
||||
create_session_request->sender_f_teid_for_control_plane.
|
||||
data = &sgw_s5c_teid;
|
||||
create_session_request->sender_f_teid_for_control_plane.
|
||||
len = sgw_s5c_len;
|
||||
|
||||
/* Remove PGW-S5C */
|
||||
create_session_request->pgw_s5_s8_address_for_control_plane_or_pmip.
|
||||
presence = 0;
|
||||
|
||||
/* Bearer Contexts */
|
||||
create_session_request->bearer_contexts_to_be_created.
|
||||
s5_s8_u_sgw_f_teid.presence = 1;
|
||||
create_session_request->bearer_contexts_to_be_created.
|
||||
s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid;
|
||||
create_session_request->bearer_contexts_to_be_created.
|
||||
s5_s8_u_sgw_f_teid.len = sgw_s5u_len;
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
||||
ogs_assert(sess->gnode);
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &recv_message->h, pkbuf, sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
}
|
||||
|
||||
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
||||
|
||||
|
@ -541,20 +611,15 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
*/
|
||||
if (flags & OGS_PFCP_MODIFY_REMOVE) {
|
||||
if (flags & OGS_PFCP_MODIFY_INDIRECT) {
|
||||
bool delete_indirect_tunnel_is_done;
|
||||
|
||||
s11_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
sess->state.delete_indirect_tunnel = true;
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
delete_indirect_tunnel_is_done = true;
|
||||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
if (sess->state.delete_indirect_tunnel == false)
|
||||
delete_indirect_tunnel_is_done = false;
|
||||
}
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
|
||||
if (delete_indirect_tunnel_is_done == true) {
|
||||
sgwc_tunnel_t *tunnel = NULL, *next_tunnel = NULL;
|
||||
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t
|
||||
*gtp_rsp = NULL;
|
||||
|
@ -603,6 +668,8 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
} else {
|
||||
s5c_xact = pfcp_xact->assoc_xact;
|
||||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
if (s5c_xact) {
|
||||
ogs_assert(recv_message);
|
||||
recv_message->h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
||||
|
@ -629,6 +696,8 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
s5c_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s5c_xact);
|
||||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(recv_message);
|
||||
gtp_req = &recv_message->create_bearer_request;
|
||||
ogs_assert(gtp_req);
|
||||
|
@ -673,6 +742,8 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
s5c_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s5c_xact);
|
||||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(recv_message);
|
||||
gtp_rsp = &recv_message->create_bearer_response;
|
||||
ogs_assert(gtp_rsp);
|
||||
|
@ -720,20 +791,15 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_INDIRECT) {
|
||||
bool create_indirect_tunnel_is_done;
|
||||
|
||||
s11_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
sess->state.create_indirect_tunnel = true;
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
create_indirect_tunnel_is_done = true;
|
||||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
if (sess->state.create_indirect_tunnel == false)
|
||||
create_indirect_tunnel_is_done = false;
|
||||
}
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
|
||||
if (create_indirect_tunnel_is_done == true) {
|
||||
sgwc_tunnel_t *tunnel = NULL;
|
||||
|
||||
ogs_gtp2_create_indirect_data_forwarding_tunnel_request_t
|
||||
|
@ -853,6 +919,8 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
s11_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
|
||||
ogs_gtp2_create_session_response_t *gtp_rsp = NULL;
|
||||
ogs_gtp2_f_teid_t sgw_s11_teid;
|
||||
|
@ -902,51 +970,56 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
||||
ogs_gtp2_modify_bearer_request_t *gtp_req = NULL;
|
||||
ogs_gtp2_modify_bearer_response_t *gtp_rsp = NULL;
|
||||
#if 0 /* FIXME */
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
#endif
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
ogs_gtp2_modify_bearer_request_t *gtp_req = NULL;
|
||||
ogs_gtp2_modify_bearer_response_t *gtp_rsp = NULL;
|
||||
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
|
||||
ogs_assert(recv_message);
|
||||
gtp_req = &recv_message->modify_bearer_request;
|
||||
ogs_assert(gtp_req);
|
||||
ogs_assert(recv_message);
|
||||
gtp_req = &recv_message->modify_bearer_request;
|
||||
ogs_assert(gtp_req);
|
||||
|
||||
if (gtp_req->indication_flags.presence &&
|
||||
gtp_req->indication_flags.data &&
|
||||
gtp_req->indication_flags.len) {
|
||||
indication = gtp_req->indication_flags.data;
|
||||
}
|
||||
if (gtp_req->indication_flags.presence &&
|
||||
gtp_req->indication_flags.data &&
|
||||
gtp_req->indication_flags.len) {
|
||||
indication = gtp_req->indication_flags.data;
|
||||
}
|
||||
|
||||
if (indication && indication->handover_indication) {
|
||||
recv_message->h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||
if (indication && indication->handover_indication) {
|
||||
recv_message->h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
||||
ogs_assert(sess->gnode);
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &recv_message->h, pkbuf,
|
||||
sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
ogs_assert(sess->gnode);
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &recv_message->h, pkbuf,
|
||||
sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
|
||||
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
||||
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
||||
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
} else {
|
||||
gtp_rsp = &send_message.modify_bearer_response;
|
||||
ogs_assert(gtp_rsp);
|
||||
} else {
|
||||
gtp_rsp = &send_message.modify_bearer_response;
|
||||
ogs_assert(gtp_rsp);
|
||||
|
||||
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
memset(&cause, 0, sizeof(cause));
|
||||
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
memset(&cause, 0, sizeof(cause));
|
||||
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
gtp_rsp->cause.presence = 1;
|
||||
gtp_rsp->cause.data = &cause;
|
||||
gtp_rsp->cause.len = sizeof(cause);
|
||||
gtp_rsp->cause.presence = 1;
|
||||
gtp_rsp->cause.data = &cause;
|
||||
gtp_rsp->cause.len = sizeof(cause);
|
||||
|
||||
/* Copy Bearer-Contexts-Modified from Modify-Bearer-Request
|
||||
*
|
||||
|
@ -961,67 +1034,89 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
* both an IPv4 address and an IPv6 address
|
||||
* (see also subclause 8.22 "F-TEID").
|
||||
*/
|
||||
gtp_rsp->bearer_contexts_modified.presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified.eps_bearer_id.presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified.eps_bearer_id.u8 =
|
||||
gtp_req->bearer_contexts_to_be_modified.eps_bearer_id.u8;
|
||||
gtp_rsp->bearer_contexts_modified.
|
||||
s1_u_enodeb_f_teid.presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified.s1_u_enodeb_f_teid.data =
|
||||
gtp_req->bearer_contexts_to_be_modified.
|
||||
s1_u_enodeb_f_teid.data;
|
||||
gtp_rsp->bearer_contexts_modified.s1_u_enodeb_f_teid.len =
|
||||
gtp_req->bearer_contexts_to_be_modified.
|
||||
s1_u_enodeb_f_teid.len;
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (gtp_req->bearer_contexts_to_be_modified[i].
|
||||
presence == 0)
|
||||
break;
|
||||
if (gtp_req->bearer_contexts_to_be_modified[i].
|
||||
eps_bearer_id.presence == 0)
|
||||
break;
|
||||
if (gtp_req->bearer_contexts_to_be_modified[i].
|
||||
s1_u_enodeb_f_teid.presence == 0)
|
||||
break;
|
||||
|
||||
gtp_rsp->bearer_contexts_modified.cause.presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified.cause.len = sizeof(cause);
|
||||
gtp_rsp->bearer_contexts_modified.cause.data = &cause;
|
||||
gtp_rsp->bearer_contexts_modified[i].presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified[i].eps_bearer_id.
|
||||
presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified[i].eps_bearer_id.u8 =
|
||||
gtp_req->bearer_contexts_to_be_modified[i].
|
||||
eps_bearer_id.u8;
|
||||
gtp_rsp->bearer_contexts_modified[i].
|
||||
s1_u_enodeb_f_teid.presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified[i].
|
||||
s1_u_enodeb_f_teid.data =
|
||||
gtp_req->bearer_contexts_to_be_modified[i].
|
||||
s1_u_enodeb_f_teid.data;
|
||||
gtp_rsp->bearer_contexts_modified[i].
|
||||
s1_u_enodeb_f_teid.len =
|
||||
gtp_req->bearer_contexts_to_be_modified[i].
|
||||
s1_u_enodeb_f_teid.len;
|
||||
|
||||
send_message.h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
||||
gtp_rsp->bearer_contexts_modified[i].cause.presence = 1;
|
||||
gtp_rsp->bearer_contexts_modified[i].cause.len =
|
||||
sizeof(cause);
|
||||
gtp_rsp->bearer_contexts_modified[i].cause.data =
|
||||
&cause;
|
||||
}
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
send_message.h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
||||
|
||||
rv = ogs_gtp_xact_update_tx(s11_xact, &send_message.h, pkbuf);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
||||
rv = ogs_gtp_xact_commit(s11_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
rv = ogs_gtp_xact_update_tx(
|
||||
s11_xact, &send_message.h, pkbuf);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
rv = ogs_gtp_xact_commit(s11_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
bool release_access_bearers_is_done;
|
||||
if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
|
||||
/* It's faked method for receiving `bearer` context */
|
||||
bearer = pfcp_xact->assoc_xact;
|
||||
ogs_assert(bearer);
|
||||
|
||||
sess->state.release_access_bearers = true;
|
||||
|
||||
release_access_bearers_is_done = true;
|
||||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
if (sess->state.release_access_bearers == false)
|
||||
release_access_bearers_is_done = false;
|
||||
}
|
||||
|
||||
if (release_access_bearers_is_done == true) {
|
||||
if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
|
||||
/* It's faked method for receiving `bearer` context */
|
||||
bearer = pfcp_xact->assoc_xact;
|
||||
ogs_assert(bearer);
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_gtp_send_downlink_data_notification(
|
||||
OGS_GTP2_CAUSE_ERROR_INDICATION_RECEIVED, bearer));
|
||||
}
|
||||
|
||||
} else {
|
||||
s11_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
|
||||
} else {
|
||||
ogs_gtp2_release_access_bearers_response_t *gtp_rsp = NULL;
|
||||
|
||||
s11_xact = pfcp_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
|
||||
gtp_rsp = &send_message.release_access_bearers_response;
|
||||
ogs_assert(gtp_rsp);
|
||||
|
||||
|
@ -1052,8 +1147,6 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
}
|
||||
|
||||
void sgwc_sxa_handle_session_deletion_response(
|
||||
|
@ -1256,8 +1349,6 @@ void sgwc_sxa_handle_session_report_request(
|
|||
|
||||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
|
||||
sess->state.release_access_bearers = false;
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_sess_modification_request(sess,
|
||||
/* We only use the `assoc_xact` parameter temporarily here
|
||||
|
|
|
@ -274,12 +274,14 @@ int sgwu_pfcp_send_session_report_request(
|
|||
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
|
||||
h.seid = sess->sgwc_sxa_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
sxabuf = ogs_pfcp_build_session_report_request(h.type, report);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, sxabuf, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
|
|
@ -111,8 +111,7 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request(
|
|||
}
|
||||
|
||||
ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
||||
uint8_t type, smf_sess_t *sess, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list)
|
||||
uint8_t type, smf_sess_t *sess, ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
ogs_pfcp_urr_t *urr = NULL;
|
||||
|
@ -128,8 +127,12 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
|||
int num_of_create_far = 0;
|
||||
int num_of_update_far = 0;
|
||||
|
||||
uint64_t modify_flags = 0;
|
||||
|
||||
ogs_debug("Session Modification Request");
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
modify_flags = xact->modify_flags;
|
||||
ogs_assert(modify_flags);
|
||||
|
||||
req = &pfcp_message.pfcp_session_modification_request;
|
||||
|
@ -181,8 +184,7 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
|||
num_of_create_pdr, pdr);
|
||||
num_of_create_pdr++;
|
||||
|
||||
ogs_assert(pdr_to_create_list);
|
||||
ogs_list_add(pdr_to_create_list, &pdr->to_create_node);
|
||||
ogs_list_add(&xact->pdr_to_create_list, &pdr->to_create_node);
|
||||
|
||||
ogs_pfcp_build_create_far(
|
||||
&req->create_far[num_of_create_far],
|
||||
|
@ -237,8 +239,7 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
|||
}
|
||||
|
||||
ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
||||
uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list)
|
||||
uint8_t type, smf_bearer_t *qos_flow, ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_modification_request_t *req = NULL;
|
||||
|
@ -247,10 +248,15 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
|||
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
uint64_t modify_flags = 0;
|
||||
|
||||
ogs_debug("QoS Flow Modification Request");
|
||||
|
||||
ogs_assert(qos_flow);
|
||||
sess = qos_flow->sess;
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
modify_flags = xact->modify_flags;
|
||||
ogs_assert(modify_flags);
|
||||
|
||||
req = &pfcp_message.pfcp_session_modification_request;
|
||||
|
@ -324,8 +330,7 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
|||
&req->create_pdr[i], i, qos_flow->dl_pdr);
|
||||
i++;
|
||||
|
||||
ogs_assert(pdr_to_create_list);
|
||||
ogs_list_add(pdr_to_create_list,
|
||||
ogs_list_add(&xact->pdr_to_create_list,
|
||||
&qos_flow->dl_pdr->to_create_node);
|
||||
}
|
||||
if (qos_flow->ul_pdr) {
|
||||
|
@ -333,8 +338,7 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
|||
&req->create_pdr[i], i, qos_flow->ul_pdr);
|
||||
i++;
|
||||
|
||||
ogs_assert(pdr_to_create_list);
|
||||
ogs_list_add(pdr_to_create_list,
|
||||
ogs_list_add(&xact->pdr_to_create_list,
|
||||
&qos_flow->ul_pdr->to_create_node);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,11 +29,9 @@ extern "C" {
|
|||
ogs_pkbuf_t *smf_n4_build_session_establishment_request(
|
||||
uint8_t type, smf_sess_t *sess);
|
||||
ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
||||
uint8_t type, smf_sess_t *sess, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list);
|
||||
uint8_t type, smf_sess_t *sess, ogs_pfcp_xact_t *xact);
|
||||
ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
||||
uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags,
|
||||
ogs_list_t *pdr_to_create_list);
|
||||
uint8_t type, smf_bearer_t *qos_flow, ogs_pfcp_xact_t *xact);
|
||||
ogs_pkbuf_t *smf_n4_build_session_deletion_request(
|
||||
uint8_t type, smf_sess_t *sess);
|
||||
|
||||
|
|
|
@ -252,11 +252,11 @@ void smf_5gc_n4_handle_session_modification_response(
|
|||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
|
||||
ogs_debug("Session Modification Response [5gc]");
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(rsp);
|
||||
|
||||
ogs_debug("Session Modification Response [5gc]");
|
||||
|
||||
flags = xact->modify_flags;
|
||||
ogs_assert(flags);
|
||||
|
||||
|
@ -1017,8 +1017,19 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
linked_bearer, gtp_pti, gtp_cause));
|
||||
} else {
|
||||
/*
|
||||
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
||||
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
||||
* 1. RX : Session-Termination Request
|
||||
* 2. GX : Re-Auth-Request(Charging-Rule-Remove)
|
||||
* 3. RX : Session-Termination Answer
|
||||
* 4. PFCP Session Modification Request(Buffering)
|
||||
* 5. PFCP Session Modification Answer(Buffering)
|
||||
* 6. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
||||
* 7. E-RABReleaseCommand + Deactivate EPS bearer context request
|
||||
* 8. E-RABReleaseResponse
|
||||
* 9. UplinkNASTransport + Deactivate EPS bearer context accept
|
||||
* 10. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW-C
|
||||
* 11. PFCP Session Modification Request/Response(Remove PDR/FAR)
|
||||
* 12. SGW-C sends Delete Bearer Response(DECIATED BEARER) to SMF
|
||||
* 13. PFCP Session Modification Request/Response(Remove PDR/FAR)
|
||||
*/
|
||||
ogs_assert(bearer);
|
||||
|
||||
|
|
|
@ -309,13 +309,16 @@ int smf_5gc_pfcp_send_session_establishment_request(
|
|||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_stream = stream;
|
||||
|
||||
n4buf = smf_n4_build_session_establishment_request(h.type, sess);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->assoc_stream = stream;
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -332,8 +335,6 @@ int smf_5gc_pfcp_send_session_modification_request(
|
|||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
|
||||
ogs_assert(sess);
|
||||
if ((flags & OGS_PFCP_MODIFY_ERROR_INDICATION) == 0)
|
||||
ogs_assert(stream);
|
||||
|
@ -342,17 +343,17 @@ int smf_5gc_pfcp_send_session_modification_request(
|
|||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_session_modification_request(
|
||||
h.type, sess, flags, &pdr_to_create_list);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_stream = stream;
|
||||
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
|
||||
|
||||
ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list);
|
||||
n4buf = smf_n4_build_session_modification_request(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
if (duration) {
|
||||
ogs_pfcp_xact_delayed_commit(xact, duration);
|
||||
|
@ -375,8 +376,6 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
|
|||
ogs_pfcp_xact_t *xact = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
|
||||
ogs_assert(qos_flow);
|
||||
sess = qos_flow->sess;
|
||||
ogs_assert(sess);
|
||||
|
@ -385,18 +384,18 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
|
|||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_qos_flow_modification_request(
|
||||
h.type, qos_flow, flags, &pdr_to_create_list);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, qos_flow_5gc_timeout, qos_flow);
|
||||
sess->pfcp_node, qos_flow_5gc_timeout, qos_flow);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_stream = stream;
|
||||
xact->modify_flags = flags;
|
||||
|
||||
ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list);
|
||||
n4buf = smf_n4_build_qos_flow_modification_request(h.type, qos_flow, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -419,14 +418,17 @@ int smf_5gc_pfcp_send_session_deletion_request(
|
|||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->assoc_stream = stream;
|
||||
xact->delete_trigger = trigger;
|
||||
|
||||
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
xact->assoc_stream = stream;
|
||||
xact->delete_trigger = trigger;
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -448,16 +450,18 @@ int smf_epc_pfcp_send_session_establishment_request(
|
|||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_session_establishment_request(h.type, sess);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_epc_timeout, sess);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->epc = true; /* EPC PFCP transaction */
|
||||
xact->assoc_xact = gtp_xact;
|
||||
|
||||
n4buf = smf_n4_build_session_establishment_request(h.type, sess);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
|
@ -473,20 +477,13 @@ int smf_epc_pfcp_send_session_modification_request(
|
|||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_session_modification_request(
|
||||
h.type, sess, flags, &pdr_to_create_list);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_epc_timeout, sess);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->epc = true; /* EPC PFCP transaction */
|
||||
|
@ -496,7 +493,11 @@ int smf_epc_pfcp_send_session_modification_request(
|
|||
xact->gtp_pti = gtp_pti;
|
||||
xact->gtp_cause = gtp_cause;
|
||||
|
||||
ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list);
|
||||
n4buf = smf_n4_build_session_modification_request(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -514,8 +515,6 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
ogs_pfcp_xact_t *xact = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
OGS_LIST(pdr_to_create_list);
|
||||
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
@ -524,12 +523,8 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_qos_flow_modification_request(
|
||||
h.type, bearer, flags, &pdr_to_create_list);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, bearer_epc_timeout, bearer);
|
||||
sess->pfcp_node, bearer_epc_timeout, bearer);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->epc = true; /* EPC PFCP transaction */
|
||||
|
@ -539,7 +534,11 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
xact->gtp_pti = gtp_pti;
|
||||
xact->gtp_cause = gtp_cause;
|
||||
|
||||
ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list);
|
||||
n4buf = smf_n4_build_qos_flow_modification_request(h.type, bearer, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -561,11 +560,7 @@ int smf_epc_pfcp_send_session_deletion_request(
|
|||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_epc_timeout, sess);
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
xact->epc = true; /* EPC PFCP transaction */
|
||||
|
@ -593,6 +588,12 @@ int smf_epc_pfcp_send_session_deletion_request(
|
|||
*/
|
||||
xact->assoc_xact = gtp_xact;
|
||||
|
||||
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
|
|
|
@ -263,19 +263,19 @@ ogs_pkbuf_t *smf_s5c_build_modify_bearer_response(
|
|||
rsp->cause.data = &cause;
|
||||
rsp->cause.len = sizeof(cause);
|
||||
|
||||
rsp->bearer_contexts_modified.presence = 1;
|
||||
rsp->bearer_contexts_modified.eps_bearer_id.presence = 1;
|
||||
rsp->bearer_contexts_modified.eps_bearer_id.u8 =
|
||||
req->bearer_contexts_to_be_modified.eps_bearer_id.u8;
|
||||
rsp->bearer_contexts_modified.s1_u_enodeb_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_modified.s1_u_enodeb_f_teid.data =
|
||||
req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.data;
|
||||
rsp->bearer_contexts_modified.s1_u_enodeb_f_teid.len =
|
||||
req->bearer_contexts_to_be_modified.s1_u_enodeb_f_teid.len;
|
||||
rsp->bearer_contexts_modified[0].presence = 1;
|
||||
rsp->bearer_contexts_modified[0].eps_bearer_id.presence = 1;
|
||||
rsp->bearer_contexts_modified[0].eps_bearer_id.u8 =
|
||||
req->bearer_contexts_to_be_modified[0].eps_bearer_id.u8;
|
||||
rsp->bearer_contexts_modified[0].s1_u_enodeb_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_modified[0].s1_u_enodeb_f_teid.data =
|
||||
req->bearer_contexts_to_be_modified[0].s1_u_enodeb_f_teid.data;
|
||||
rsp->bearer_contexts_modified[0].s1_u_enodeb_f_teid.len =
|
||||
req->bearer_contexts_to_be_modified[0].s1_u_enodeb_f_teid.len;
|
||||
|
||||
rsp->bearer_contexts_modified.cause.presence = 1;
|
||||
rsp->bearer_contexts_modified.cause.len = sizeof(cause);
|
||||
rsp->bearer_contexts_modified.cause.data = &cause;
|
||||
rsp->bearer_contexts_modified[0].cause.presence = 1;
|
||||
rsp->bearer_contexts_modified[0].cause.len = sizeof(cause);
|
||||
rsp->bearer_contexts_modified[0].cause.data = &cause;
|
||||
|
||||
/* build */
|
||||
gtp_message.h.type = type;
|
||||
|
|
|
@ -212,16 +212,6 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
|
||||
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
|
||||
|
||||
/* Remove all previous bearer */
|
||||
smf_bearer_remove_all(sess);
|
||||
|
||||
/* Setup Default Bearer */
|
||||
bearer = smf_bearer_add(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
/* Set Bearer EBI */
|
||||
bearer->ebi = req->bearer_contexts_to_be_created.eps_bearer_id.u8;
|
||||
|
||||
/* Control Plane(DL) : SGW-S5C */
|
||||
sgw_s5c_teid = req->sender_f_teid_for_control_plane.data;
|
||||
ogs_assert(sgw_s5c_teid);
|
||||
|
@ -232,6 +222,16 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
||||
/* Remove all previous bearer */
|
||||
smf_bearer_remove_all(sess);
|
||||
|
||||
/* Setup Default Bearer */
|
||||
bearer = smf_bearer_add(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
/* Set Bearer EBI */
|
||||
bearer->ebi = req->bearer_contexts_to_be_created.eps_bearer_id.u8;
|
||||
|
||||
switch (sess->gtp_rat_type) {
|
||||
case OGS_GTP2_RAT_TYPE_EUTRAN:
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created.
|
||||
|
@ -350,10 +350,13 @@ void smf_s5c_handle_modify_bearer_request(
|
|||
ogs_assert(xact);
|
||||
ogs_assert(req);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context");
|
||||
ogs_error("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
@ -363,16 +366,53 @@ void smf_s5c_handle_modify_bearer_request(
|
|||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
/* Control Plane(DL) : SGW-S5C */
|
||||
if (req->sender_f_teid_for_control_plane.presence == 1) {
|
||||
ogs_gtp2_f_teid_t *sgw_s5c_teid =
|
||||
req->sender_f_teid_for_control_plane.data;
|
||||
ogs_assert(sgw_s5c_teid);
|
||||
sess->sgw_s5c_teid = be32toh(sgw_s5c_teid->teid);
|
||||
rv = ogs_gtp2_f_teid_to_ip(sgw_s5c_teid, &sess->sgw_s5c_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
/* TODO: Update remote GTP-U IP addr + TEID in the UPF through PFCP, similar
|
||||
* to what is done in smf_gn_handle_update_pdp_context_request()
|
||||
*/
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
}
|
||||
|
||||
#if 0 /* TODO */
|
||||
switch (sess->gtp_rat_type) {
|
||||
case OGS_GTP2_RAT_TYPE_EUTRAN:
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created.
|
||||
s5_s8_u_sgw_f_teid.data;
|
||||
ogs_assert(sgw_s5u_teid);
|
||||
bearer->sgw_s5u_teid = be32toh(sgw_s5u_teid->teid);
|
||||
rv = ogs_gtp2_f_teid_to_ip(sgw_s5u_teid, &bearer->sgw_s5u_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
break;
|
||||
case OGS_GTP2_RAT_TYPE_WLAN:
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created.
|
||||
s2b_u_epdg_f_teid_5.data;
|
||||
ogs_assert(sgw_s5u_teid);
|
||||
bearer->sgw_s5u_teid = be32toh(sgw_s5u_teid->teid);
|
||||
rv = ogs_gtp2_f_teid_to_ip(sgw_s5u_teid, &bearer->sgw_s5u_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
break;
|
||||
default:
|
||||
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
ogs_debug(" SGW_S5U_TEID[0x%x] PGW_S5U_TEID[0x%x]",
|
||||
bearer->sgw_s5u_teid, bearer->pgw_s5u_teid);
|
||||
#endif
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||
|
@ -414,23 +454,49 @@ void smf_s5c_handle_create_bearer_response(
|
|||
{
|
||||
int rv;
|
||||
uint8_t cause_value;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
ogs_gtp2_f_teid_t *sgw_s5u_teid, *pgw_s5u_teid;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
ogs_pfcp_far_t *dl_far = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(rsp);
|
||||
|
||||
bearer = xact->data;
|
||||
ogs_assert(bearer);
|
||||
|
||||
ogs_debug("Create Bearer Response");
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(xact);
|
||||
bearer = xact->data;
|
||||
ogs_assert(bearer);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_bearer_modification_request(
|
||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->bearer_contexts.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
@ -458,42 +524,19 @@ void smf_s5c_handle_create_bearer_response(
|
|||
|
||||
if (!pgw_s5u_teid) {
|
||||
ogs_error("No PGW TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (!sgw_s5u_teid) {
|
||||
ogs_error("No SGW TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context in TEID");
|
||||
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (rsp->bearer_contexts.cause.presence) {
|
||||
cause = rsp->bearer_contexts.cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
} else {
|
||||
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
if (rsp->bearer_contexts.cause.presence == 0) {
|
||||
ogs_error("No Bearer Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
|
@ -506,6 +549,43 @@ void smf_s5c_handle_create_bearer_response(
|
|||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
cause = rsp->bearer_contexts.cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_bearer_modification_request(
|
||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
|
||||
return;
|
||||
}
|
||||
|
||||
cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_bearer_modification_request(
|
||||
bearer, NULL, OGS_PFCP_MODIFY_REMOVE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP2_CAUSE_UNDEFINED_VALUE));
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(bearer);
|
||||
ogs_assert(sess);
|
||||
|
||||
/* Find the Bearer by PGW-S5U-TEID */
|
||||
ogs_assert(pgw_s5u_teid);
|
||||
bearer = smf_bearer_find_by_pgw_s5u_teid(sess, be32toh(pgw_s5u_teid->teid));
|
||||
|
@ -549,25 +629,46 @@ void smf_s5c_handle_update_bearer_response(
|
|||
{
|
||||
int rv;
|
||||
uint8_t cause_value;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
uint64_t gtp_flags = 0;
|
||||
uint64_t pfcp_flags = 0;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(rsp);
|
||||
gtp_flags = xact->update_flags;
|
||||
ogs_assert(gtp_flags);
|
||||
|
||||
bearer = xact->data;
|
||||
ogs_assert(bearer);
|
||||
|
||||
ogs_debug("Update Bearer Response");
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(xact);
|
||||
gtp_flags = xact->update_flags;
|
||||
ogs_assert(gtp_flags);
|
||||
bearer = xact->data;
|
||||
ogs_assert(bearer);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (rsp->bearer_contexts.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
@ -577,45 +678,49 @@ void smf_s5c_handle_update_bearer_response(
|
|||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context in TEID");
|
||||
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (rsp->bearer_contexts.cause.presence) {
|
||||
cause = rsp->bearer_contexts.cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
} else {
|
||||
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
if (rsp->cause.presence == 0) {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
if (rsp->bearer_contexts.cause.presence == 0) {
|
||||
ogs_error("No Bearer Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
cause = rsp->bearer_contexts.cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
||||
ogs_debug("Update Bearer Response : SGW[0x%x] --> SMF[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
||||
|
@ -646,27 +751,32 @@ bool smf_s5c_handle_delete_bearer_response(
|
|||
uint8_t cause_value;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(rsp);
|
||||
|
||||
ogs_debug("Delete Bearer Response");
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
/********************
|
||||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(xact);
|
||||
bearer = xact->data;
|
||||
ogs_assert(bearer);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context in TEID");
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
if (!sess)
|
||||
ogs_error("No Context in TEID");
|
||||
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
if (rsp->linked_eps_bearer_id.presence) {
|
||||
/*
|
||||
|
@ -689,7 +799,6 @@ bool smf_s5c_handle_delete_bearer_response(
|
|||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
/* Release entire session: */
|
||||
return true;
|
||||
|
@ -724,17 +833,18 @@ bool smf_s5c_handle_delete_bearer_response(
|
|||
cause = rsp->bearer_contexts.cause.data;
|
||||
ogs_assert(cause);
|
||||
|
||||
cause_value = cause->value;
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
} else {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
} else {
|
||||
ogs_warn("GTP Failed [CAUSE:%d]", cause_value);
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
|
@ -865,15 +975,50 @@ void smf_s5c_handle_bearer_resource_command(
|
|||
int tft_delete = 0;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(sess);
|
||||
ogs_assert(cmd);
|
||||
|
||||
ogs_debug("[PGW] Bearer Resource Command");
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
ogs_debug("Bearer Resource Command");
|
||||
|
||||
/************************
|
||||
* Check Session Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
if (cmd->linked_eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
uint8_t ebi = cmd->linked_eps_bearer_id.u8;
|
||||
|
||||
if (cmd->eps_bearer_id.presence)
|
||||
ebi = cmd->eps_bearer_id.u8;
|
||||
|
||||
bearer = smf_bearer_find_by_ebi(sess, ebi);
|
||||
if (!bearer) {
|
||||
ogs_error("No Context for Linked EPS Bearer ID[%d:%d]",
|
||||
cmd->linked_eps_bearer_id.u8, ebi);
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
|
||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (cmd->procedure_transaction_id.presence == 0) {
|
||||
ogs_error("No PTI");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
@ -888,35 +1033,20 @@ void smf_s5c_handle_bearer_resource_command(
|
|||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (!sess) {
|
||||
ogs_warn("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
uint8_t ebi = cmd->linked_eps_bearer_id.u8;
|
||||
|
||||
if (cmd->eps_bearer_id.presence)
|
||||
ebi = cmd->eps_bearer_id.u8;
|
||||
|
||||
bearer = smf_bearer_find_by_ebi(sess, ebi);
|
||||
if (!bearer)
|
||||
ogs_error("No Context for Linked EPS Bearer ID[%d]",
|
||||
cmd->linked_eps_bearer_id.u8);
|
||||
}
|
||||
|
||||
if (!bearer) {
|
||||
ogs_error("No Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
|
||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(bearer);
|
||||
ogs_assert(sess);
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
||||
decoded = ogs_gtp2_parse_tft(&tft, &cmd->traffic_aggregate_description);
|
||||
ogs_assert(cmd->traffic_aggregate_description.len == decoded);
|
||||
|
|
|
@ -732,7 +732,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_sbi_xact_remove(sbi_xact);
|
||||
|
||||
sess = smf_sess_cycle(sess);
|
||||
ogs_assert(sess);
|
||||
if (!sess) {
|
||||
ogs_error("Session has already been removed");
|
||||
break;
|
||||
}
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
smf_ue = smf_ue_cycle(smf_ue);
|
||||
|
|
|
@ -277,12 +277,14 @@ int upf_pfcp_send_session_report_request(
|
|||
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
|
||||
h.seid = sess->smf_n4_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
n4buf = ogs_pfcp_build_session_report_request(h.type, report);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, n4buf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
|
Loading…
Reference in New Issue