forked from acouzens/open5gs
parent
11d4be1779
commit
4d2f7726b9
|
@ -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-22 03:19:22.029355 by acetcom
|
||||
* Created on: 2022-05-01 15:20:04.462265 by acetcom
|
||||
* from 29274-g30.docx
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -2063,6 +2063,7 @@ ogs_tlv_desc_t ogs_gtp2_tlv_desc_create_session_request =
|
|||
&ogs_gtp2_tlv_desc_twmi_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_trace_information_0,
|
||||
&ogs_gtp2_tlv_desc_recovery_0,
|
||||
|
@ -2128,6 +2129,7 @@ ogs_tlv_desc_t ogs_gtp2_tlv_desc_create_session_response =
|
|||
&ogs_gtp2_tlv_desc_ebi_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_recovery_0,
|
||||
&ogs_gtp2_tlv_desc_fqdn_0,
|
||||
|
|
|
@ -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-22 03:19:22.024556 by acetcom
|
||||
* Created on: 2022-05-01 15:20:04.456902 by acetcom
|
||||
* from 29274-g30.docx
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -758,7 +758,7 @@ typedef struct ogs_gtp2_create_session_request_s {
|
|||
ogs_gtp2_tlv_ebi_t linked_eps_bearer_id;
|
||||
ogs_gtp2_tlv_twmi_t trusted_wlan_mode_indication;
|
||||
ogs_gtp2_tlv_pco_t protocol_configuration_options;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_created;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_created[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_removed;
|
||||
ogs_gtp2_tlv_trace_information_t trace_information;
|
||||
ogs_gtp2_tlv_recovery_t recovery;
|
||||
|
@ -818,7 +818,7 @@ typedef struct ogs_gtp2_create_session_response_s {
|
|||
ogs_gtp2_tlv_ambr_t aggregate_maximum_bit_rate;
|
||||
ogs_gtp2_tlv_ebi_t linked_eps_bearer_id;
|
||||
ogs_gtp2_tlv_pco_t protocol_configuration_options;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_created;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_created[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_marked_for_removal;
|
||||
ogs_gtp2_tlv_recovery_t recovery;
|
||||
ogs_gtp2_tlv_fqdn_t charging_gateway_name;
|
||||
|
@ -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[8];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_to_be_modified[OGS_BEARER_PER_UE];
|
||||
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[8];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts_modified[OGS_BEARER_PER_UE];
|
||||
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;
|
||||
|
@ -1160,14 +1160,14 @@ typedef struct ogs_gtp2_create_indirect_data_forwarding_tunnel_request_s {
|
|||
ogs_gtp2_tlv_mei_t me_identity;
|
||||
ogs_gtp2_tlv_indication_t indication_flags;
|
||||
ogs_gtp2_tlv_f_teid_t sender_f_teid_for_control_plane;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts[8];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_tlv_recovery_t recovery;
|
||||
} ogs_gtp2_create_indirect_data_forwarding_tunnel_request_t;
|
||||
|
||||
typedef struct ogs_gtp2_create_indirect_data_forwarding_tunnel_response_s {
|
||||
ogs_gtp2_tlv_cause_t cause;
|
||||
ogs_gtp2_tlv_f_teid_t sender_f_teid_for_control_plane;
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts[8];
|
||||
ogs_gtp2_tlv_bearer_context_t bearer_contexts[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_tlv_recovery_t recovery;
|
||||
} ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t;
|
||||
|
||||
|
|
|
@ -252,6 +252,7 @@ void ogs_gtp2_send_error_message(
|
|||
tlv = &errmsg.bearer_resource_failure_indication.cause;
|
||||
break;
|
||||
default:
|
||||
ogs_fatal("Invalid message[%d]", type);
|
||||
ogs_assert_if_reached();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -580,9 +580,9 @@ 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') 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'):
|
||||
if ((k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts') or (k == 'Create Session Request' and ies["ie_value"] == 'Bearer Contexts to be created') or (k == 'Create Session Response' and ies["ie_value"] == 'Bearer Contexts created') 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")
|
||||
v_lower(ies["ie_value"]) + "[OGS_BEARER_PER_UE];\n")
|
||||
else:
|
||||
f.write(" ogs_gtp2_tlv_" + v_lower(ies["ie_type"]) + "_t " + \
|
||||
v_lower(ies["ie_value"]) + ";\n")
|
||||
|
@ -671,7 +671,7 @@ 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') 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'):
|
||||
if ((k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts') or (k == 'Create Session Request' and ies["ie_value"] == 'Bearer Contexts to be created') or (k == 'Create Session Response' and ies["ie_value"] == 'Bearer Contexts created') 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")
|
||||
|
|
|
@ -99,6 +99,7 @@ typedef struct ogs_gtp_xact_s {
|
|||
#define OGS_GTP_DELETE_SEND_UE_CONTEXT_RELEASE_COMMAND 4
|
||||
#define OGS_GTP_DELETE_HANDLE_PDN_CONNECTIVITY_REQUEST 5
|
||||
#define OGS_GTP_DELETE_UE_CONTEXT_REMOVE 6
|
||||
#define OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST 7
|
||||
int delete_action;
|
||||
|
||||
#define OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND 1
|
||||
|
|
|
@ -138,6 +138,7 @@ typedef struct ogs_pfcp_pdr_s {
|
|||
uint32_t index;
|
||||
|
||||
ogs_lnode_t to_create_node;
|
||||
ogs_lnode_t to_modify_node;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
|
|
|
@ -170,7 +170,7 @@ bool ogs_pfcp_up_handle_association_setup_response(
|
|||
}
|
||||
|
||||
bool ogs_pfcp_up_handle_pdr(
|
||||
ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *recvbuf,
|
||||
ogs_pfcp_pdr_t *pdr, uint8_t type, ogs_pkbuf_t *recvbuf,
|
||||
ogs_pfcp_user_plane_report_t *report)
|
||||
{
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
|
@ -178,6 +178,7 @@ bool ogs_pfcp_up_handle_pdr(
|
|||
bool buffering;
|
||||
|
||||
ogs_assert(recvbuf);
|
||||
ogs_assert(type);
|
||||
ogs_assert(pdr);
|
||||
ogs_assert(report);
|
||||
|
||||
|
@ -198,7 +199,7 @@ bool ogs_pfcp_up_handle_pdr(
|
|||
if (far->apply_action & OGS_PFCP_APPLY_ACTION_FORW) {
|
||||
|
||||
/* Forward packet */
|
||||
ogs_pfcp_send_g_pdu(pdr, sendbuf);
|
||||
ogs_pfcp_send_g_pdu(pdr, type, sendbuf);
|
||||
|
||||
} else if (far->apply_action & OGS_PFCP_APPLY_ACTION_BUFF) {
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ bool ogs_pfcp_up_handle_association_setup_response(
|
|||
ogs_pfcp_association_setup_response_t *req);
|
||||
|
||||
bool ogs_pfcp_up_handle_pdr(
|
||||
ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *recvbuf,
|
||||
ogs_pfcp_pdr_t *pdr, uint8_t type, ogs_pkbuf_t *recvbuf,
|
||||
ogs_pfcp_user_plane_report_t *report);
|
||||
bool ogs_pfcp_up_handle_error_indication(
|
||||
ogs_pfcp_far_t *far, ogs_pfcp_user_plane_report_t *report);
|
||||
|
|
|
@ -283,7 +283,8 @@ int ogs_pfcp_up_send_association_setup_response(ogs_pfcp_xact_t *xact,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void ogs_pfcp_send_g_pdu(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *sendbuf)
|
||||
void ogs_pfcp_send_g_pdu(
|
||||
ogs_pfcp_pdr_t *pdr, uint8_t type, ogs_pkbuf_t *sendbuf)
|
||||
{
|
||||
ogs_gtp_node_t *gnode = NULL;
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
|
@ -292,6 +293,7 @@ void ogs_pfcp_send_g_pdu(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *sendbuf)
|
|||
ogs_gtp2_extension_header_t ext_hdesc;
|
||||
|
||||
ogs_assert(pdr);
|
||||
ogs_assert(type);
|
||||
ogs_assert(sendbuf);
|
||||
|
||||
far = pdr->far;
|
||||
|
@ -314,7 +316,7 @@ void ogs_pfcp_send_g_pdu(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *sendbuf)
|
|||
memset(>p_hdesc, 0, sizeof(gtp_hdesc));
|
||||
memset(&ext_hdesc, 0, sizeof(ext_hdesc));
|
||||
|
||||
gtp_hdesc.type = OGS_GTPU_MSGTYPE_GPDU;
|
||||
gtp_hdesc.type = type;
|
||||
gtp_hdesc.teid = far->outer_header_creation.teid;
|
||||
if (pdr->qer && pdr->qer->qfi)
|
||||
ext_hdesc.qos_flow_identifier = pdr->qer->qfi;
|
||||
|
@ -374,7 +376,8 @@ void ogs_pfcp_send_buffered_packet(ogs_pfcp_pdr_t *pdr)
|
|||
if (far && far->gnode) {
|
||||
if (far->apply_action & OGS_PFCP_APPLY_ACTION_FORW) {
|
||||
for (i = 0; i < far->num_of_buffered_packet; i++) {
|
||||
ogs_pfcp_send_g_pdu(pdr, far->buffered_packet[i]);
|
||||
ogs_pfcp_send_g_pdu(
|
||||
pdr, OGS_GTPU_MSGTYPE_GPDU, far->buffered_packet[i]);
|
||||
}
|
||||
far->num_of_buffered_packet = 0;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,8 @@ int ogs_pfcp_up_send_association_setup_request(ogs_pfcp_node_t *node,
|
|||
int ogs_pfcp_up_send_association_setup_response(ogs_pfcp_xact_t *xact,
|
||||
uint8_t cause);
|
||||
|
||||
void ogs_pfcp_send_g_pdu(ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *sendbuf);
|
||||
void ogs_pfcp_send_g_pdu(
|
||||
ogs_pfcp_pdr_t *pdr, uint8_t type, ogs_pkbuf_t *sendbuf);
|
||||
int ogs_pfcp_send_end_marker(ogs_pfcp_pdr_t *pdr);
|
||||
|
||||
void ogs_pfcp_send_buffered_packet(ogs_pfcp_pdr_t *pdr);
|
||||
|
|
|
@ -754,7 +754,7 @@ void amf_sess_select_nf(amf_sess_t *sess, OpenAPI_nf_type_e nf_type);
|
|||
|
||||
void amf_sess_select_smf(amf_sess_t *sess);
|
||||
|
||||
#define SESSION_SYNC_DONE(__aMF, __sTATE) \
|
||||
#define AMF_SESSION_SYNC_DONE(__aMF, __sTATE) \
|
||||
(amf_sess_xact_state_count(__aMF, __sTATE) == 0)
|
||||
int amf_sess_xact_count(amf_ue_t *amf_ue);
|
||||
int amf_sess_xact_state_count(amf_ue_t *amf_ue, int state);
|
||||
|
|
|
@ -223,9 +223,9 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
sess, pdu_session_resource_setup_request,
|
||||
ogs_pkbuf_copy(n2smbuf));
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue,
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
|
||||
SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST)) {
|
||||
|
||||
if (!PCF_AM_POLICY_ASSOCIATED(amf_ue)) {
|
||||
|
@ -247,9 +247,9 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
sess, pdu_session_resource_setup_request,
|
||||
ogs_pkbuf_copy(n2smbuf));
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue,
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
|
||||
SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
nas_5gs_send_service_accept(amf_ue));
|
||||
|
@ -261,7 +261,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
AMF_SESS_STORE_N2_TRANSFER(
|
||||
sess, handover_request, ogs_pkbuf_copy(n2smbuf));
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue,
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue,
|
||||
AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_handover_request(amf_ue));
|
||||
|
@ -367,7 +367,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
sess, path_switch_request_ack,
|
||||
ogs_pkbuf_copy(n2smbuf));
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_path_switch_ack(sess));
|
||||
|
||||
|
@ -390,7 +390,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
AMF_SESS_STORE_N2_TRANSFER(
|
||||
sess, handover_command, ogs_pkbuf_copy(n2smbuf));
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
ngap_send_handover_command(amf_ue));
|
||||
|
||||
|
@ -497,7 +497,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
* 6. UEContextReleaseComplete
|
||||
*/
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ogs_assert(amf_ue->deactivation.group);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
|
@ -573,7 +573,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
|
||||
} else if (state == AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL) {
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ran_ue_t *source_ue = NULL, *target_ue = NULL;
|
||||
|
||||
source_ue = amf_ue->ran_ue;
|
||||
|
@ -593,7 +593,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
/* Nothing to do */
|
||||
|
||||
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_LO_CONNREFUSED) {
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
||||
|
||||
amf_ue_deassociate(amf_ue);
|
||||
|
@ -608,7 +608,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
}
|
||||
|
||||
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_RESET_ALL) {
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
||||
|
||||
amf_ue_deassociate(amf_ue);
|
||||
|
@ -631,7 +631,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
|||
}
|
||||
|
||||
} else if (state == AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL) {
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
ran_ue_t *iter = NULL;
|
||||
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
||||
|
||||
|
@ -797,9 +797,9 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
|
|||
* 2. Release All SM contexts
|
||||
* 3. Registration accept
|
||||
*/
|
||||
if (SESSION_SYNC_DONE(
|
||||
if (AMF_SESSION_SYNC_DONE(
|
||||
amf_ue, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
|
||||
SESSION_SYNC_DONE(
|
||||
AMF_SESSION_SYNC_DONE(
|
||||
amf_ue, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST)) {
|
||||
|
||||
if (!PCF_AM_POLICY_ASSOCIATED(amf_ue)) {
|
||||
|
@ -820,14 +820,14 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
|
|||
* 2. Release All SM contexts
|
||||
* 3. Service accept
|
||||
*/
|
||||
if (SESSION_SYNC_DONE(amf_ue, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
|
||||
SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST))
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
|
||||
AMF_SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST))
|
||||
ogs_assert(OGS_OK ==
|
||||
nas_5gs_send_service_accept(amf_ue));
|
||||
|
||||
} else {
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
if (AMF_SESSION_SYNC_DONE(amf_ue, state)) {
|
||||
|
||||
if (state == AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE) {
|
||||
/*
|
||||
|
|
|
@ -119,7 +119,7 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
|
|||
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
|
||||
if (MME_HAVE_SGW_S1U_PATH(sess)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_delete_session_request(sess,
|
||||
mme_gtp_send_delete_session_request(mme_ue->sgw_ue, sess,
|
||||
OGS_GTP_DELETE_SEND_DEACTIVATE_BEARER_CONTEXT_REQUEST));
|
||||
} else {
|
||||
ogs_assert(OGS_OK ==
|
||||
|
@ -306,7 +306,7 @@ void esm_state_active(ogs_fsm_t *s, mme_event_t *e)
|
|||
mme_ue->imsi_bcd, sess->pti, bearer->ebi);
|
||||
if (MME_HAVE_SGW_S1U_PATH(sess)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_delete_session_request(sess,
|
||||
mme_gtp_send_delete_session_request(mme_ue->sgw_ue, sess,
|
||||
OGS_GTP_DELETE_SEND_DEACTIVATE_BEARER_CONTEXT_REQUEST));
|
||||
} else {
|
||||
ogs_assert(OGS_OK ==
|
||||
|
|
|
@ -2039,14 +2039,9 @@ sgw_ue_t *sgw_ue_add(mme_sgw_t *sgw)
|
|||
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(
|
||||
sgw_ue->t_s11_holding = ogs_timer_add(
|
||||
ogs_app()->timer_mgr, mme_timer_s11_holding_timer_expire, sgw_ue);
|
||||
ogs_assert(sgw_ue->t_gtp2_holding);
|
||||
ogs_assert(sgw_ue->t_s11_holding);
|
||||
|
||||
sgw_ue->sgw = sgw;
|
||||
|
||||
|
@ -2065,8 +2060,8 @@ void sgw_ue_remove(sgw_ue_t *sgw_ue)
|
|||
|
||||
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_assert(sgw_ue->t_s11_holding);
|
||||
ogs_timer_delete(sgw_ue->t_s11_holding);
|
||||
|
||||
ogs_pool_free(&sgw_ue_pool, sgw_ue);
|
||||
}
|
||||
|
@ -2092,11 +2087,6 @@ 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);
|
||||
|
@ -2105,7 +2095,7 @@ sgw_ue_t *sgw_ue_cycle(sgw_ue_t *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;
|
||||
sgw_ue_t *old_source_ue = NULL, *source_ue = NULL, *target_ue = NULL;
|
||||
mme_sgw_t *current = NULL, *changed = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
@ -2120,6 +2110,13 @@ sgw_relocation_e sgw_ue_check_if_relocated(mme_ue_t *mme_ue)
|
|||
changed = changed_sgw_node(current, enb_ue);
|
||||
if (!changed) return SGW_WITHOUT_RELOCATION;
|
||||
|
||||
/* Check if Old Source UE */
|
||||
old_source_ue = sgw_ue_cycle(source_ue->source_ue);
|
||||
if (old_source_ue) {
|
||||
sgw_ue_source_deassociate_target(old_source_ue);
|
||||
sgw_ue_remove(old_source_ue);
|
||||
}
|
||||
|
||||
target_ue = sgw_ue_cycle(source_ue->target_ue);
|
||||
if (target_ue) {
|
||||
ogs_error("SGW-UE source has already been associated with target");
|
||||
|
@ -2260,6 +2257,10 @@ 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.
|
||||
|
@ -2438,6 +2439,11 @@ 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;
|
||||
|
|
|
@ -277,7 +277,6 @@ struct sgw_ue_s {
|
|||
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 */
|
||||
|
||||
/*
|
||||
|
@ -288,8 +287,8 @@ struct sgw_ue_s {
|
|||
*/
|
||||
int session_context_will_deleted;
|
||||
|
||||
/* GTPv2-C Holding timer for removing this context */
|
||||
ogs_timer_t *t_gtp2_holding;
|
||||
/* S11 Holding timer for removing this context */
|
||||
ogs_timer_t *t_s11_holding;
|
||||
|
||||
/* Related Context */
|
||||
union {
|
||||
|
@ -351,6 +350,8 @@ struct mme_ue_s {
|
|||
ogs_nas_eps_guti_t guti;
|
||||
} current, next;
|
||||
|
||||
uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */
|
||||
|
||||
uint16_t vlr_ostream_id; /* SCTP output stream id for VLR */
|
||||
|
||||
/* UE Info */
|
||||
|
@ -533,8 +534,8 @@ struct mme_ue_s {
|
|||
|
||||
#define MAX_NUM_OF_GTP_COUNTER 16
|
||||
|
||||
#define GTP_COUNTER_MODIFY_BEARER_BY_PATH_SWITCH 1
|
||||
#define GTP_COUNTER_MODIFY_BEARER_BY_E_RAB_MODIFICATION 2
|
||||
#define GTP_COUNTER_CREATE_SESSION_BY_PATH_SWITCH 1
|
||||
#define GTP_COUNTER_DELETE_SESSION_BY_PATH_SWITCH 2
|
||||
struct {
|
||||
uint8_t request;
|
||||
uint8_t response;
|
||||
|
@ -638,6 +639,8 @@ typedef struct mme_bearer_s {
|
|||
ogs_ip_t enb_s1u_ip;
|
||||
uint32_t sgw_s1u_teid;
|
||||
ogs_ip_t sgw_s1u_ip;
|
||||
uint32_t pgw_s5u_teid;
|
||||
ogs_ip_t pgw_s5u_ip;
|
||||
|
||||
uint32_t target_s1u_teid; /* Target S1U TEID from HO-Req-Ack */
|
||||
ogs_ip_t target_s1u_ip; /* Target S1U ADDR from HO-Req-Ack */
|
||||
|
@ -734,7 +737,6 @@ 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 {
|
||||
|
@ -758,6 +760,7 @@ 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);
|
||||
|
|
|
@ -747,10 +747,10 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (hdr->avp_value->os.len) {
|
||||
if (hdr->avp_value->os.data && hdr->avp_value->os.len) {
|
||||
mme_ue->msisdn_len = hdr->avp_value->os.len;
|
||||
memcpy(mme_ue->msisdn,
|
||||
hdr->avp_value->os.data, mme_ue->msisdn_len);
|
||||
memcpy(mme_ue->msisdn, hdr->avp_value->os.data,
|
||||
ogs_min(mme_ue->msisdn_len, OGS_MAX_MSISDN_LEN));
|
||||
ogs_buffer_to_bcd(mme_ue->msisdn,
|
||||
mme_ue->msisdn_len, mme_ue->msisdn_bcd);
|
||||
}
|
||||
|
@ -769,10 +769,10 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg)
|
|||
if (avpch1) {
|
||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||
ogs_assert(ret == 0);
|
||||
if (hdr->avp_value->os.len) {
|
||||
if (hdr->avp_value->os.data && hdr->avp_value->os.len) {
|
||||
mme_ue->a_msisdn_len = hdr->avp_value->os.len;
|
||||
memcpy(mme_ue->a_msisdn,
|
||||
hdr->avp_value->os.data, mme_ue->a_msisdn_len);
|
||||
memcpy(mme_ue->a_msisdn, hdr->avp_value->os.data,
|
||||
ogs_min(mme_ue->a_msisdn_len, OGS_MAX_MSISDN_LEN));
|
||||
ogs_buffer_to_bcd(mme_ue->a_msisdn,
|
||||
mme_ue->a_msisdn_len, mme_ue->a_msisdn_bcd);
|
||||
}
|
||||
|
|
|
@ -267,27 +267,26 @@ int mme_gtp_send_modify_bearer_request(
|
|||
return rv;
|
||||
}
|
||||
|
||||
int mme_gtp_send_delete_session_request(mme_sess_t *sess, int action)
|
||||
int mme_gtp_send_delete_session_request(
|
||||
sgw_ue_t *sgw_ue, mme_sess_t *sess, int action)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *s11buf = NULL;
|
||||
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 = sgw_ue->sgw_s11_teid;
|
||||
|
||||
s11buf = mme_s11_build_delete_session_request(h.type, sess);
|
||||
s11buf = mme_s11_build_delete_session_request(h.type, sess, action);
|
||||
ogs_expect_or_return_val(s11buf, OGS_ERROR);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, s11buf, timeout, sess);
|
||||
|
@ -330,7 +329,7 @@ void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action)
|
|||
OGS_FSM_CHECK(&bearer->sm, esm_state_pdn_will_disconnect)) {
|
||||
ogs_warn("PDN will disconnect[EBI:%d]", bearer->ebi);
|
||||
} else {
|
||||
mme_gtp_send_delete_session_request(sess, action);
|
||||
mme_gtp_send_delete_session_request(sgw_ue, sess, action);
|
||||
}
|
||||
} else {
|
||||
mme_sess_remove(sess);
|
||||
|
|
|
@ -32,7 +32,8 @@ 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_ue_t *mme_ue, int uli_presence, int modify_action);
|
||||
int mme_gtp_send_delete_session_request(mme_sess_t *sess, int action);
|
||||
int mme_gtp_send_delete_session_request(
|
||||
sgw_ue_t *sgw_ue, 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(
|
||||
mme_bearer_t *bearer, uint8_t cause_value);
|
||||
|
|
|
@ -37,9 +37,13 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
char uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
ogs_gtp2_f_teid_t mme_s11_teid, pgw_s5c_teid;
|
||||
int len;
|
||||
ogs_gtp2_f_teid_t enb_s1u_teid[OGS_BEARER_PER_UE];
|
||||
int enb_s1u_len[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_f_teid_t pgw_s5u_teid[OGS_BEARER_PER_UE];
|
||||
int pgw_s5u_len[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_ambr_t ambr;
|
||||
ogs_gtp2_bearer_qos_t bearer_qos;
|
||||
char bearer_qos_buf[GTP2_BEARER_QOS_LEN];
|
||||
char bearer_qos_buf[OGS_BEARER_PER_UE][GTP2_BEARER_QOS_LEN];
|
||||
ogs_gtp2_ue_timezone_t ue_timezone;
|
||||
struct timeval now;
|
||||
struct tm time_exp;
|
||||
|
@ -51,8 +55,6 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
session = sess->session;
|
||||
ogs_assert(session);
|
||||
ogs_assert(session->name);
|
||||
bearer = mme_default_bearer_in_sess(sess);
|
||||
ogs_assert(bearer);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = mme_ue->sgw_ue;
|
||||
|
@ -65,7 +67,7 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
|
||||
ogs_debug("Create Session Request");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
ogs_assert(mme_ue->imsi_len);
|
||||
|
@ -105,7 +107,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(sgw_ue->mme_s11_teid);
|
||||
mme_s11_teid.teid = htobe32(mme_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);
|
||||
|
@ -257,20 +259,58 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
req->protocol_configuration_options.len = sess->ue_pco.length;
|
||||
}
|
||||
|
||||
req->bearer_contexts_to_be_created.presence = 1;
|
||||
req->bearer_contexts_to_be_created.eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts_to_be_created.eps_bearer_id.u8 = bearer->ebi;
|
||||
int i = 0;
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
/* Bearer Context : EBI */
|
||||
req->bearer_contexts_to_be_created[i].presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
|
||||
/* 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], &enb_s1u_len[i]));
|
||||
req->bearer_contexts_to_be_created[i].s1_u_enodeb_f_teid.
|
||||
presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].s1_u_enodeb_f_teid.data =
|
||||
&enb_s1u_teid[i];
|
||||
req->bearer_contexts_to_be_created[i].s1_u_enodeb_f_teid.len =
|
||||
enb_s1u_len[i];
|
||||
|
||||
/* Data Plane(DL) : PGW-S5U */
|
||||
memset(&pgw_s5u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
pgw_s5u_teid[i].interface_type = OGS_GTP2_F_TEID_S5_S8_PGW_GTP_U;
|
||||
pgw_s5u_teid[i].teid = htobe32(bearer->pgw_s5u_teid);
|
||||
ogs_assert(OGS_OK == ogs_gtp2_ip_to_f_teid(
|
||||
&bearer->pgw_s5u_ip, &pgw_s5u_teid[i], &pgw_s5u_len[i]));
|
||||
req->bearer_contexts_to_be_created[i].s5_s8_u_sgw_f_teid.
|
||||
presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].s5_s8_u_sgw_f_teid.data =
|
||||
&pgw_s5u_teid[i];
|
||||
req->bearer_contexts_to_be_created[i].s5_s8_u_sgw_f_teid.len =
|
||||
pgw_s5u_len[i];
|
||||
}
|
||||
|
||||
memset(&bearer_qos, 0, sizeof(bearer_qos));
|
||||
bearer_qos.qci = session->qos.index;
|
||||
bearer_qos.priority_level = session->qos.arp.priority_level;
|
||||
bearer_qos.pre_emption_capability = session->qos.arp.pre_emption_capability;
|
||||
bearer_qos.pre_emption_capability =
|
||||
session->qos.arp.pre_emption_capability;
|
||||
bearer_qos.pre_emption_vulnerability =
|
||||
session->qos.arp.pre_emption_vulnerability;
|
||||
req->bearer_contexts_to_be_created.bearer_level_qos.presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].bearer_level_qos.presence = 1;
|
||||
ogs_gtp2_build_bearer_qos(
|
||||
&req->bearer_contexts_to_be_created.bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf, GTP2_BEARER_QOS_LEN);
|
||||
&req->bearer_contexts_to_be_created[i].bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf[i], GTP2_BEARER_QOS_LEN);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* UE Time Zone */
|
||||
memset(&ue_timezone, 0, sizeof(ue_timezone));
|
||||
|
@ -305,7 +345,7 @@ ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
|||
ogs_gtp2_modify_bearer_request_t *req = NULL;
|
||||
|
||||
ogs_gtp2_f_teid_t enb_s1u_teid[OGS_BEARER_PER_UE];
|
||||
int len, i;
|
||||
int enb_s1u_len[OGS_BEARER_PER_UE], i;
|
||||
ogs_gtp2_uli_t uli;
|
||||
char uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
|
||||
|
@ -326,7 +366,7 @@ ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
|||
req = >p_message.modify_bearer_request;
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
i = 0;
|
||||
ogs_list_for_each_entry(
|
||||
|
@ -345,12 +385,13 @@ ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
|||
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));
|
||||
ogs_assert(OGS_OK == ogs_gtp2_ip_to_f_teid(
|
||||
&bearer->enb_s1u_ip, &enb_s1u_teid[i], &enb_s1u_len[i]));
|
||||
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;
|
||||
req->bearer_contexts_to_be_modified[i].s1_u_enodeb_f_teid.len =
|
||||
enb_s1u_len[i];
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -409,7 +450,7 @@ ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
|||
}
|
||||
|
||||
ogs_pkbuf_t *mme_s11_build_delete_session_request(
|
||||
uint8_t type, mme_sess_t *sess)
|
||||
uint8_t type, mme_sess_t *sess, int action)
|
||||
{
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_delete_session_request_t *req =
|
||||
|
@ -421,19 +462,14 @@ 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]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -453,7 +489,11 @@ ogs_pkbuf_t *mme_s11_build_delete_session_request(
|
|||
uli_buf, OGS_GTP2_MAX_ULI_LEN);
|
||||
|
||||
memset(&indication, 0, sizeof(ogs_gtp2_indication_t));
|
||||
if (action == OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST) {
|
||||
indication.scope_indication = 1;
|
||||
} else {
|
||||
indication.operation_indication = 1;
|
||||
}
|
||||
req->indication_flags.presence = 1;
|
||||
req->indication_flags.data = &indication;
|
||||
req->indication_flags.len = sizeof(ogs_gtp2_indication_t);
|
||||
|
@ -490,7 +530,7 @@ ogs_pkbuf_t *mme_s11_build_create_bearer_response(
|
|||
|
||||
ogs_debug("Create Bearer Response");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -591,7 +631,7 @@ ogs_pkbuf_t *mme_s11_build_update_bearer_response(
|
|||
|
||||
ogs_debug("Update Bearer Response");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -670,7 +710,7 @@ ogs_pkbuf_t *mme_s11_build_delete_bearer_response(
|
|||
|
||||
ogs_debug("Delete Bearer Response");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -824,7 +864,7 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
|||
|
||||
ogs_debug("Create Indirect Data Forwarding Tunnel Request");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
|
@ -906,7 +946,7 @@ ogs_pkbuf_t *mme_s11_build_bearer_resource_command(
|
|||
|
||||
ogs_debug("Bearer Resource Command");
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
ogs_assert(nas_message);
|
||||
switch (nas_message->esm.h.message_type) {
|
||||
|
|
|
@ -29,7 +29,7 @@ ogs_pkbuf_t *mme_s11_build_create_session_request(
|
|||
ogs_pkbuf_t *mme_s11_build_modify_bearer_request(
|
||||
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);
|
||||
uint8_t type, mme_sess_t *sess, int action);
|
||||
ogs_pkbuf_t *mme_s11_build_create_bearer_response(
|
||||
uint8_t type, mme_bearer_t *bearer, uint8_t cause_value);
|
||||
ogs_pkbuf_t *mme_s11_build_update_bearer_response(
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "mme-event.h"
|
||||
#include "mme-sm.h"
|
||||
#include "mme-context.h"
|
||||
#include "mme-timer.h"
|
||||
|
||||
#include "s1ap-path.h"
|
||||
#include "mme-gtp-path.h"
|
||||
|
@ -77,19 +78,21 @@ void mme_s11_handle_echo_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_create_session_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_create_session_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
int rv, i;
|
||||
uint8_t cause_value = 0;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
ogs_gtp2_f_teid_t *sgw_s11_teid = NULL;
|
||||
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
||||
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL;
|
||||
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
||||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *source_ue = NULL, *target_ue = NULL;
|
||||
ogs_session_t *session = NULL;
|
||||
ogs_gtp2_bearer_qos_t bearer_qos;
|
||||
ogs_gtp2_ambr_t *ambr = NULL;
|
||||
|
@ -109,38 +112,28 @@ void mme_s11_handle_create_session_response(
|
|||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
source_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(source_ue);
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
target_ue = sgw_ue_cycle(source_ue->target_ue);
|
||||
ogs_assert(target_ue);
|
||||
} else {
|
||||
target_ue = source_ue;
|
||||
ogs_assert(target_ue);
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue_from_teid) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
|
||||
rsp->bearer_contexts_created.eps_bearer_id.u8);
|
||||
|
||||
if (!bearer) {
|
||||
ogs_error("No Context for EPS Bearer ID[%d]",
|
||||
rsp->bearer_contexts_created.eps_bearer_id.u8);
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -162,15 +155,26 @@ void mme_s11_handle_create_session_response(
|
|||
ogs_error("No S11 TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
|
||||
/* No need S5C TEID in PathSwitchRequest */
|
||||
|
||||
} else {
|
||||
|
||||
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 S5C TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.s1_u_enodeb_f_teid.presence == 0) {
|
||||
ogs_error("No S1U TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
|
||||
}
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
|
||||
/* No need S5C TEID in PathSwitchRequest */
|
||||
|
||||
} else {
|
||||
|
||||
if (rsp->pdn_address_allocation.presence) {
|
||||
ogs_paa_t paa;
|
||||
|
||||
|
@ -185,15 +189,12 @@ void mme_s11_handle_create_session_response(
|
|||
ogs_error("No PDN Address Allocation");
|
||||
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) {
|
||||
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
||||
|
@ -210,7 +211,12 @@ void mme_s11_handle_create_session_response(
|
|||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
cause = rsp->bearer_contexts_created.cause.data;
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (rsp->bearer_contexts_created[i].cause.presence == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
cause = rsp->bearer_contexts_created[i].cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -223,6 +229,7 @@ void mme_s11_handle_create_session_response(
|
|||
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
@ -246,25 +253,87 @@ void mme_s11_handle_create_session_response(
|
|||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
session = sess->session;
|
||||
ogs_assert(session);
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(source_ue);
|
||||
ogs_assert(target_ue);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
mme_ue->mme_s11_teid, target_ue->sgw_s11_teid);
|
||||
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (rsp->bearer_contexts_created[i].presence == 0) {
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.presence == 0) {
|
||||
ogs_error("No SGW-S1U TEID");
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.presence == 0) {
|
||||
ogs_error("No PGW-S5U TEID");
|
||||
break;
|
||||
}
|
||||
|
||||
/* EPS Bearer ID */
|
||||
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
|
||||
rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
||||
if (!bearer) {
|
||||
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Data Plane(UL) : SGW-S1U */
|
||||
sgw_s1u_teid = rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.data;
|
||||
bearer->sgw_s1u_teid = be32toh(sgw_s1u_teid->teid);
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip));
|
||||
|
||||
/* Data Plane(UL) : PGW-S5U */
|
||||
pgw_s5u_teid = rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.data;
|
||||
bearer->pgw_s5u_teid = be32toh(pgw_s5u_teid->teid);
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &bearer->pgw_s5u_ip));
|
||||
|
||||
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d] PGW_S5U_TEID[%d]",
|
||||
bearer->enb_s1u_teid, bearer->sgw_s1u_teid, bearer->pgw_s5u_teid);
|
||||
}
|
||||
|
||||
/* Bearer Level QoS */
|
||||
if (rsp->bearer_contexts_created[0].bearer_level_qos.presence) {
|
||||
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
&rsp->bearer_contexts_created[0].bearer_level_qos);
|
||||
ogs_assert(decoded ==
|
||||
rsp->bearer_contexts_created[0].bearer_level_qos.len);
|
||||
session->qos.index = bearer_qos.qci;
|
||||
session->qos.arp.priority_level = bearer_qos.priority_level;
|
||||
session->qos.arp.pre_emption_capability =
|
||||
bearer_qos.pre_emption_capability;
|
||||
session->qos.arp.pre_emption_vulnerability =
|
||||
bearer_qos.pre_emption_vulnerability;
|
||||
}
|
||||
|
||||
/* Control Plane(UL) : SGW-S11 */
|
||||
sgw_s11_teid = rsp->sender_f_teid_for_control_plane.data;
|
||||
sgw_ue->sgw_s11_teid = be32toh(sgw_s11_teid->teid);
|
||||
target_ue->sgw_s11_teid = be32toh(sgw_s11_teid->teid);
|
||||
|
||||
/* Control Plane(UL) : PGW-S5C */
|
||||
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence) {
|
||||
pgw_s5c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.data;
|
||||
sess->pgw_s5c_teid = be32toh(pgw_s5c_teid->teid);
|
||||
}
|
||||
|
||||
/* PDN Addresss Allocation */
|
||||
if (rsp->pdn_address_allocation.presence) {
|
||||
memcpy(&session->paa, rsp->pdn_address_allocation.data,
|
||||
rsp->pdn_address_allocation.len);
|
||||
}
|
||||
|
||||
/* PCO */
|
||||
if (rsp->protocol_configuration_options.presence) {
|
||||
|
@ -273,10 +342,10 @@ void mme_s11_handle_create_session_response(
|
|||
}
|
||||
|
||||
/* Bearer QoS */
|
||||
if (rsp->bearer_contexts_created.bearer_level_qos.presence) {
|
||||
if (rsp->bearer_contexts_created[0].bearer_level_qos.presence) {
|
||||
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
&rsp->bearer_contexts_created.bearer_level_qos);
|
||||
ogs_assert(rsp->bearer_contexts_created.bearer_level_qos.len ==
|
||||
&rsp->bearer_contexts_created[0].bearer_level_qos);
|
||||
ogs_assert(rsp->bearer_contexts_created[0].bearer_level_qos.len ==
|
||||
decoded);
|
||||
session->qos.index = bearer_qos.qci;
|
||||
session->qos.arp.priority_level = bearer_qos.priority_level;
|
||||
|
@ -293,18 +362,6 @@ void mme_s11_handle_create_session_response(
|
|||
session->ambr.uplink = be32toh(ambr->uplink) * 1000;
|
||||
}
|
||||
|
||||
/* Data Plane(UL) : SGW-S1U */
|
||||
sgw_s1u_teid = rsp->bearer_contexts_created.s1_u_enodeb_f_teid.data;
|
||||
bearer->sgw_s1u_teid = be32toh(sgw_s1u_teid->teid);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d]",
|
||||
bearer->enb_s1u_teid, bearer->sgw_s1u_teid);
|
||||
|
||||
rv = ogs_gtp2_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
||||
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
|
||||
mme_ue->csmap = csmap;
|
||||
|
@ -327,7 +384,15 @@ void mme_s11_handle_create_session_response(
|
|||
nas_eps_send_activate_default_bearer_context_request(
|
||||
bearer, create_action));
|
||||
} else if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
||||
ogs_error("OK");
|
||||
|
||||
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_CREATE_SESSION_BY_PATH_SWITCH,
|
||||
ogs_timer_start(source_ue->t_s11_holding,
|
||||
mme_timer_cfg(MME_TIMER_S11_HOLDING)->duration);
|
||||
|
||||
sgw_ue_associate_mme_ue(target_ue, mme_ue);
|
||||
ogs_assert(OGS_OK == s1ap_send_path_switch_ack(mme_ue, true));
|
||||
);
|
||||
|
||||
} else {
|
||||
ogs_fatal("Invalid Create Session Action[%d]", create_action);
|
||||
ogs_assert_if_reached();
|
||||
|
@ -335,7 +400,7 @@ void mme_s11_handle_create_session_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_modify_bearer_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_modify_bearer_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
|
@ -344,6 +409,7 @@ void mme_s11_handle_modify_bearer_response(
|
|||
ogs_gtp2_cause_t *cause = NULL;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(rsp);
|
||||
|
||||
|
@ -353,19 +419,21 @@ void mme_s11_handle_modify_bearer_response(
|
|||
* Check Transaction
|
||||
********************/
|
||||
ogs_assert(xact);
|
||||
modify_action = xact->modify_action;
|
||||
mme_ue = xact->data;
|
||||
ogs_assert(mme_ue);
|
||||
modify_action = xact->modify_action;
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue_from_teid) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
@ -411,11 +479,11 @@ void mme_s11_handle_modify_bearer_response(
|
|||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
switch (modify_action) {
|
||||
case OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST:
|
||||
ogs_assert(OGS_OK == s1ap_send_path_switch_ack(mme_ue));
|
||||
ogs_assert(OGS_OK == s1ap_send_path_switch_ack(mme_ue, false));
|
||||
break;
|
||||
case OGS_GTP_MODIFY_IN_E_RAB_MODIFICATION:
|
||||
ogs_assert(OGS_OK == s1ap_send_e_rab_modification_confirm(mme_ue));
|
||||
|
@ -426,14 +494,15 @@ void mme_s11_handle_modify_bearer_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_delete_session_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_delete_session_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
uint8_t cause_value = 0;
|
||||
int action = 0;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *source_ue = NULL, *target_ue = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
ogs_assert(rsp);
|
||||
|
||||
|
@ -449,15 +518,26 @@ void mme_s11_handle_delete_session_response(
|
|||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
target_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(target_ue);
|
||||
|
||||
if (action == OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST) {
|
||||
source_ue = sgw_ue_cycle(target_ue->source_ue);
|
||||
ogs_assert(source_ue);
|
||||
} else {
|
||||
source_ue = target_ue;
|
||||
ogs_assert(source_ue);
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
************************/
|
||||
if (!sgw_ue)
|
||||
if (!mme_ue_from_teid) {
|
||||
ogs_error("No Context in TEID");
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
|
@ -474,12 +554,13 @@ void mme_s11_handle_delete_session_response(
|
|||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(sess);
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(target_ue);
|
||||
ogs_assert(source_ue);
|
||||
|
||||
if (sgw_ue)
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, source_ue->sgw_s11_teid);
|
||||
|
||||
if (action == OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST) {
|
||||
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
|
||||
|
@ -541,6 +622,20 @@ void mme_s11_handle_delete_session_response(
|
|||
mme_ue_remove(mme_ue);
|
||||
return;
|
||||
|
||||
} else if (action == OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST) {
|
||||
|
||||
/* Don't have to remove Session in X2 Handover with SGW relocation */
|
||||
ogs_assert(source_ue);
|
||||
|
||||
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_DELETE_SESSION_BY_PATH_SWITCH,
|
||||
|
||||
sgw_ue_source_deassociate_target(source_ue);
|
||||
sgw_ue_remove(source_ue);
|
||||
|
||||
);
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
ogs_fatal("Invalid action = %d", action);
|
||||
ogs_assert_if_reached();
|
||||
|
@ -553,16 +648,16 @@ void mme_s11_handle_delete_session_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_create_bearer_request(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_create_bearer_request_t *req)
|
||||
{
|
||||
int rv;
|
||||
uint8_t cause_value = 0;
|
||||
mme_bearer_t *bearer = NULL, *default_bearer = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL;
|
||||
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
||||
ogs_gtp2_bearer_qos_t bearer_qos;
|
||||
|
||||
ogs_assert(xact);
|
||||
|
@ -571,16 +666,16 @@ void mme_s11_handle_create_bearer_request(
|
|||
ogs_debug("Create Bearer Response");
|
||||
|
||||
/***********************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
***********************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
mme_ue = sgw_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (req->linked_eps_bearer_id.presence == 0) {
|
||||
ogs_error("No Linked EBI");
|
||||
|
@ -617,7 +712,11 @@ void mme_s11_handle_create_bearer_request(
|
|||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts.s1_u_enodeb_f_teid.presence == 0) {
|
||||
ogs_error("No GTP TEID");
|
||||
ogs_error("No SGW-S1U TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts.s4_u_sgsn_f_teid.presence == 0) {
|
||||
ogs_error("No PGW-S5U TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts.bearer_level_qos.presence == 0) {
|
||||
|
@ -646,7 +745,7 @@ void mme_s11_handle_create_bearer_request(
|
|||
ogs_assert(bearer);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
/* Set PTI */
|
||||
sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
|
||||
|
@ -658,8 +757,14 @@ void mme_s11_handle_create_bearer_request(
|
|||
/* Data Plane(UL) : SGW-S1U */
|
||||
sgw_s1u_teid = req->bearer_contexts.s1_u_enodeb_f_teid.data;
|
||||
bearer->sgw_s1u_teid = be32toh(sgw_s1u_teid->teid);
|
||||
rv = ogs_gtp2_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip));
|
||||
|
||||
/* Data Plane(UL) : PGW-S5U */
|
||||
pgw_s5u_teid = req->bearer_contexts.s4_u_sgsn_f_teid.data;
|
||||
bearer->pgw_s5u_teid = be32toh(pgw_s5u_teid->teid);
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &bearer->pgw_s5u_ip));
|
||||
|
||||
/* Bearer QoS */
|
||||
ogs_expect_or_return(ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
|
@ -721,13 +826,13 @@ void mme_s11_handle_create_bearer_request(
|
|||
}
|
||||
|
||||
void mme_s11_handle_update_bearer_request(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_update_bearer_request_t *req)
|
||||
{
|
||||
uint8_t cause_value = 0;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
ogs_gtp2_bearer_qos_t bearer_qos;
|
||||
|
||||
ogs_assert(xact);
|
||||
|
@ -736,16 +841,16 @@ void mme_s11_handle_update_bearer_request(
|
|||
ogs_debug("Update Bearer Request");
|
||||
|
||||
/***********************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
***********************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
mme_ue = sgw_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (req->bearer_contexts.presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
|
@ -783,7 +888,7 @@ void mme_s11_handle_update_bearer_request(
|
|||
ogs_assert(sess);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
/* Set PTI */
|
||||
sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
|
||||
|
@ -856,14 +961,14 @@ void mme_s11_handle_update_bearer_request(
|
|||
}
|
||||
|
||||
void mme_s11_handle_delete_bearer_request(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_delete_bearer_request_t *req)
|
||||
{
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(req);
|
||||
|
@ -871,16 +976,16 @@ void mme_s11_handle_delete_bearer_request(
|
|||
ogs_debug("Delete Bearer Request");
|
||||
|
||||
/***********************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
***********************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
mme_ue = sgw_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (req->linked_eps_bearer_id.presence == 1) {
|
||||
/*
|
||||
|
@ -943,7 +1048,7 @@ void mme_s11_handle_delete_bearer_request(
|
|||
ogs_assert(sess);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
/* Set PTI */
|
||||
sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
|
||||
|
@ -971,7 +1076,7 @@ void mme_s11_handle_delete_bearer_request(
|
|||
}
|
||||
|
||||
void mme_s11_handle_release_access_bearers_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_release_access_bearers_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
|
@ -979,7 +1084,8 @@ void mme_s11_handle_release_access_bearers_response(
|
|||
int action = 0;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
mme_ue_t *mme_ue = NULL;;
|
||||
sgw_ue_t *sgw_ue = NULL;;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
|
||||
|
@ -995,15 +1101,18 @@ void mme_s11_handle_release_access_bearers_response(
|
|||
ogs_assert(action);
|
||||
mme_ue = xact->data;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
/***********************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
***********************/
|
||||
if (!sgw_ue)
|
||||
if (!mme_ue_from_teid) {
|
||||
ogs_error("No Context in TEID");
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check Cause Value
|
||||
|
@ -1021,10 +1130,10 @@ void mme_s11_handle_release_access_bearers_response(
|
|||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (sgw_ue)
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
|
@ -1125,13 +1234,13 @@ void mme_s11_handle_release_access_bearers_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_downlink_data_notification(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_downlink_data_notification_t *noti)
|
||||
{
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(noti);
|
||||
|
@ -1139,16 +1248,16 @@ void mme_s11_handle_downlink_data_notification(
|
|||
ogs_debug("Downlink Data Notification");
|
||||
|
||||
/************************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue) {
|
||||
ogs_error("No UE Context");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
} else {
|
||||
mme_ue = sgw_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (noti->eps_bearer_id.presence == 0) {
|
||||
ogs_error("No Bearer ID");
|
||||
|
@ -1181,7 +1290,7 @@ void mme_s11_handle_downlink_data_notification(
|
|||
ogs_assert(bearer);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
/*
|
||||
* Save Transaction. It will be handled after ECM-Connected
|
||||
|
@ -1263,14 +1372,15 @@ void mme_s11_handle_downlink_data_notification(
|
|||
}
|
||||
|
||||
void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
uint8_t cause_value = 0;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
enb_ue_t *source_ue = NULL;
|
||||
int i;
|
||||
|
||||
|
@ -1286,16 +1396,18 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
|||
ogs_assert(xact);
|
||||
mme_ue = xact->data;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue_from_teid) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
@ -1341,7 +1453,7 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
|||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
for (i = 0; rsp->bearer_contexts[i].presence; i++) {
|
||||
if (rsp->bearer_contexts[i].eps_bearer_id.presence == 0) {
|
||||
|
@ -1378,7 +1490,7 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
|
@ -1386,6 +1498,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
|||
ogs_gtp2_cause_t *cause = NULL;
|
||||
int action = 0;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_assert(rsp);
|
||||
|
||||
|
@ -1399,16 +1512,18 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
|||
ogs_assert(action);
|
||||
mme_ue = xact->data;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
/************************
|
||||
* Check SGW-UE Context
|
||||
* Check MME-UE Context
|
||||
************************/
|
||||
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
if (!sgw_ue) {
|
||||
if (!mme_ue_from_teid) {
|
||||
ogs_error("No Context in TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
|
@ -1454,7 +1569,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
|||
ogs_assert(sgw_ue);
|
||||
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
mme_ue_clear_indirect_tunnel(mme_ue);
|
||||
|
||||
|
@ -1470,7 +1585,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
|||
}
|
||||
|
||||
void mme_s11_handle_bearer_resource_failure_indication(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
||||
ogs_gtp2_bearer_resource_failure_indication_t *ind)
|
||||
{
|
||||
int rv;
|
||||
|
@ -1479,6 +1594,7 @@ void mme_s11_handle_bearer_resource_failure_indication(
|
|||
mme_bearer_t *bearer = NULL;
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
sgw_ue_t *sgw_ue = NULL;
|
||||
|
||||
ogs_debug("Bearer Resource Failure Indication");
|
||||
|
||||
|
@ -1492,11 +1608,13 @@ void mme_s11_handle_bearer_resource_failure_indication(
|
|||
ogs_assert(sess);
|
||||
mme_ue = sess->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
|
||||
if (!sgw_ue)
|
||||
if (!mme_ue_from_teid)
|
||||
ogs_error("No Context in TEID");
|
||||
|
||||
/********************
|
||||
|
@ -1516,10 +1634,10 @@ void mme_s11_handle_bearer_resource_failure_indication(
|
|||
* Check ALL Context
|
||||
********************/
|
||||
ogs_assert(mme_ue);
|
||||
ogs_assert(sgw_ue);
|
||||
|
||||
if (sgw_ue)
|
||||
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
||||
sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
nas_eps_send_bearer_resource_modification_reject(
|
||||
|
|
|
@ -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, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_create_session_response_t *rsp);
|
||||
void mme_s11_handle_modify_bearer_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_modify_bearer_response_t *rsp);
|
||||
void mme_s11_handle_delete_session_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_delete_session_response_t *rsp);
|
||||
void mme_s11_handle_create_bearer_request(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_create_bearer_request_t *rsp);
|
||||
void mme_s11_handle_update_bearer_request(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_update_bearer_request_t *rsp);
|
||||
void mme_s11_handle_delete_bearer_request(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_delete_bearer_request_t *rsp);
|
||||
|
||||
void mme_s11_handle_release_access_bearers_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_release_access_bearers_response_t *rsp);
|
||||
void mme_s11_handle_downlink_data_notification(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_downlink_data_notification_t *noti);
|
||||
void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_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, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp);
|
||||
|
||||
void mme_s11_handle_bearer_resource_failure_indication(
|
||||
ogs_gtp_xact_t *xact, sgw_ue_t *sgw_ue,
|
||||
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
||||
ogs_gtp2_bearer_resource_failure_indication_t *ind);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -521,6 +521,15 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
|
||||
rv = ogs_gtp_xact_receive(gnode, >p_message.h, &xact);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_pkbuf_free(pkbuf);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 5.5.2 in spec 29.274
|
||||
*
|
||||
|
@ -552,21 +561,7 @@ 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" */
|
||||
sgw_ue = sgw_ue_find_by_mme_s11_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
if (sgw_ue) {
|
||||
gnode = sgw_ue->gnode;
|
||||
ogs_assert(gnode);
|
||||
} else {
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_receive(gnode, >p_message.h, &xact);
|
||||
if (rv != OGS_OK) {
|
||||
ogs_pkbuf_free(pkbuf);
|
||||
break;
|
||||
mme_ue = mme_ue_find_by_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
switch (gtp_message.h.type) {
|
||||
|
@ -578,49 +573,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, sgw_ue, >p_message.create_session_response);
|
||||
xact, mme_ue, >p_message.create_session_response);
|
||||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE:
|
||||
mme_s11_handle_modify_bearer_response(
|
||||
xact, sgw_ue, >p_message.modify_bearer_response);
|
||||
xact, mme_ue, >p_message.modify_bearer_response);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
|
||||
mme_s11_handle_delete_session_response(
|
||||
xact, sgw_ue, >p_message.delete_session_response);
|
||||
xact, mme_ue, >p_message.delete_session_response);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
|
||||
mme_s11_handle_create_bearer_request(
|
||||
xact, sgw_ue, >p_message.create_bearer_request);
|
||||
xact, mme_ue, >p_message.create_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
|
||||
mme_s11_handle_update_bearer_request(
|
||||
xact, sgw_ue, >p_message.update_bearer_request);
|
||||
xact, mme_ue, >p_message.update_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
|
||||
mme_s11_handle_delete_bearer_request(
|
||||
xact, sgw_ue, >p_message.delete_bearer_request);
|
||||
xact, mme_ue, >p_message.delete_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
|
||||
mme_s11_handle_release_access_bearers_response(
|
||||
xact, sgw_ue, >p_message.release_access_bearers_response);
|
||||
xact, mme_ue, >p_message.release_access_bearers_response);
|
||||
break;
|
||||
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE:
|
||||
mme_s11_handle_downlink_data_notification(
|
||||
xact, sgw_ue, >p_message.downlink_data_notification);
|
||||
xact, mme_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, sgw_ue,
|
||||
xact, mme_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, sgw_ue,
|
||||
xact, mme_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, sgw_ue,
|
||||
xact, mme_ue,
|
||||
>p_message.bearer_resource_failure_indication);
|
||||
break;
|
||||
default:
|
||||
|
@ -630,6 +625,37 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
ogs_pkbuf_free(pkbuf);
|
||||
break;
|
||||
|
||||
case MME_EVT_S11_TIMER:
|
||||
sgw_ue = e->sgw_ue;
|
||||
ogs_assert(sgw_ue);
|
||||
mme_ue = sgw_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
switch (e->timer_id) {
|
||||
case MME_TIMER_S11_HOLDING:
|
||||
|
||||
GTP_COUNTER_CLEAR(mme_ue,
|
||||
GTP_COUNTER_DELETE_SESSION_BY_PATH_SWITCH);
|
||||
|
||||
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
||||
|
||||
GTP_COUNTER_INCREMENT(
|
||||
mme_ue, GTP_COUNTER_DELETE_SESSION_BY_PATH_SWITCH);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_delete_session_request(
|
||||
sgw_ue, sess,
|
||||
OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown timer[%s:%d]",
|
||||
mme_timer_get_name(e->timer_id), e->timer_id);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MME_EVT_SGSAP_LO_SCTP_COMM_UP:
|
||||
sock = e->sock;
|
||||
ogs_assert(sock);
|
||||
|
|
|
@ -1556,7 +1556,8 @@ ogs_pkbuf_t *s1ap_build_mme_configuration_transfer(
|
|||
return ogs_s1ap_encode(&pdu);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *s1ap_build_path_switch_ack(mme_ue_t *mme_ue)
|
||||
ogs_pkbuf_t *s1ap_build_path_switch_ack(
|
||||
mme_ue_t *mme_ue, bool e_rab_to_switched_in_uplink_list)
|
||||
{
|
||||
S1AP_S1AP_PDU_t pdu;
|
||||
S1AP_SuccessfulOutcome_t *successfulOutcome = NULL;
|
||||
|
@ -1565,8 +1566,11 @@ ogs_pkbuf_t *s1ap_build_path_switch_ack(mme_ue_t *mme_ue)
|
|||
S1AP_PathSwitchRequestAcknowledgeIEs_t *ie = NULL;
|
||||
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
|
||||
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
|
||||
S1AP_E_RABToBeSwitchedULList_t *E_RABToBeSwitchedULList = NULL;
|
||||
S1AP_SecurityContext_t *SecurityContext = NULL;
|
||||
|
||||
mme_sess_t *sess = NULL;
|
||||
mme_bearer_t *bearer = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
@ -1608,6 +1612,18 @@ ogs_pkbuf_t *s1ap_build_path_switch_ack(mme_ue_t *mme_ue)
|
|||
|
||||
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
|
||||
|
||||
if (e_rab_to_switched_in_uplink_list == true) {
|
||||
ie = CALLOC(1, sizeof(S1AP_PathSwitchRequestAcknowledgeIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie);
|
||||
|
||||
ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeSwitchedULList;
|
||||
ie->criticality = S1AP_Criticality_ignore;
|
||||
ie->value.present =
|
||||
S1AP_PathSwitchRequestAcknowledgeIEs__value_PR_E_RABToBeSwitchedULList;
|
||||
|
||||
E_RABToBeSwitchedULList = &ie->value.choice.E_RABToBeSwitchedULList;
|
||||
}
|
||||
|
||||
ie = CALLOC(1, sizeof(S1AP_PathSwitchRequestAcknowledgeIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PathSwitchRequestAcknowledge->protocolIEs, ie);
|
||||
|
||||
|
@ -1624,6 +1640,31 @@ ogs_pkbuf_t *s1ap_build_path_switch_ack(mme_ue_t *mme_ue)
|
|||
*MME_UE_S1AP_ID = enb_ue->mme_ue_s1ap_id;
|
||||
*ENB_UE_S1AP_ID = enb_ue->enb_ue_s1ap_id;
|
||||
|
||||
if (e_rab_to_switched_in_uplink_list == true) {
|
||||
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
S1AP_E_RABToBeSwitchedULItemIEs_t *item = NULL;
|
||||
S1AP_E_RABToBeSwitchedULItem_t *e_rab = NULL;
|
||||
|
||||
item = CALLOC(1, sizeof(S1AP_E_RABToBeSwitchedULItemIEs_t));
|
||||
ASN_SEQUENCE_ADD(&E_RABToBeSwitchedULList->list, item);
|
||||
|
||||
item->id = S1AP_ProtocolIE_ID_id_E_RABToBeSwitchedULItem;
|
||||
item->criticality = S1AP_Criticality_ignore;
|
||||
item->value.present = S1AP_E_RABToBeSwitchedULItemIEs__value_PR_E_RABToBeSwitchedULItem;
|
||||
|
||||
e_rab = &item->value.choice.E_RABToBeSwitchedULItem;
|
||||
|
||||
e_rab->e_RAB_ID = bearer->ebi;
|
||||
|
||||
ogs_assert(OGS_OK == ogs_asn_ip_to_BIT_STRING(
|
||||
&bearer->sgw_s1u_ip, &e_rab->transportLayerAddress));
|
||||
ogs_asn_uint32_to_OCTET_STRING(
|
||||
bearer->sgw_s1u_teid, &e_rab->gTP_TEID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SecurityContext->nextHopChainingCount = mme_ue->nhcc;
|
||||
SecurityContext->nextHopParameter.size = OGS_SHA256_DIGEST_SIZE;
|
||||
SecurityContext->nextHopParameter.buf =
|
||||
|
|
|
@ -56,7 +56,8 @@ ogs_pkbuf_t *s1ap_build_paging(
|
|||
ogs_pkbuf_t *s1ap_build_mme_configuration_transfer(
|
||||
S1AP_SONConfigurationTransfer_t *son_configuration_transfer);
|
||||
|
||||
ogs_pkbuf_t *s1ap_build_path_switch_ack(mme_ue_t *mme_ue);
|
||||
ogs_pkbuf_t *s1ap_build_path_switch_ack(
|
||||
mme_ue_t *mme_ue, bool e_rab_to_switched_in_uplink_list);
|
||||
ogs_pkbuf_t *s1ap_build_path_switch_failure(
|
||||
uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id,
|
||||
S1AP_Cause_PR group, long cause);
|
||||
|
|
|
@ -1927,13 +1927,6 @@ void s1ap_handle_path_switch_request(
|
|||
mme_ue->nhcc++;
|
||||
ogs_kdf_nh_enb(mme_ue->kasme, mme_ue->nh, mme_ue->nh);
|
||||
|
||||
#if 0
|
||||
relocation = sgw_ue_check_if_relocated(mme_ue);
|
||||
#else
|
||||
relocation = SGW_WITHOUT_RELOCATION;
|
||||
#endif
|
||||
if (relocation == SGW_WITHOUT_RELOCATION) {
|
||||
|
||||
ogs_list_init(&mme_ue->bearer_to_modify_list);
|
||||
|
||||
for (i = 0; i < E_RABToBeSwitchedDLList->list.count; i++) {
|
||||
|
@ -1990,6 +1983,8 @@ void s1ap_handle_path_switch_request(
|
|||
&mme_ue->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
}
|
||||
|
||||
relocation = sgw_ue_check_if_relocated(mme_ue);
|
||||
if (relocation == SGW_WITHOUT_RELOCATION) {
|
||||
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));
|
||||
|
@ -1998,6 +1993,9 @@ void s1ap_handle_path_switch_request(
|
|||
mme_sess_t *sess = NULL;
|
||||
|
||||
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
||||
GTP_COUNTER_INCREMENT(
|
||||
mme_ue, GTP_COUNTER_CREATE_SESSION_BY_PATH_SWITCH);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
mme_gtp_send_create_session_request(
|
||||
sess, OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST));
|
||||
|
|
|
@ -415,7 +415,8 @@ int s1ap_send_e_rab_modification_confirm(mme_ue_t *mme_ue)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int s1ap_send_path_switch_ack(mme_ue_t *mme_ue)
|
||||
int s1ap_send_path_switch_ack(
|
||||
mme_ue_t *mme_ue, bool e_rab_to_switched_in_uplink_list)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *s1apbuf = NULL;
|
||||
|
@ -423,7 +424,8 @@ int s1ap_send_path_switch_ack(mme_ue_t *mme_ue)
|
|||
ogs_assert(mme_ue);
|
||||
|
||||
ogs_debug("PathSwitchAcknowledge");
|
||||
s1apbuf = s1ap_build_path_switch_ack(mme_ue);
|
||||
s1apbuf = s1ap_build_path_switch_ack(
|
||||
mme_ue, e_rab_to_switched_in_uplink_list);
|
||||
ogs_expect_or_return_val(s1apbuf, OGS_ERROR);
|
||||
|
||||
rv = nas_eps_send_to_enb(mme_ue, s1apbuf);
|
||||
|
|
|
@ -66,7 +66,8 @@ int s1ap_send_mme_configuration_transfer(
|
|||
|
||||
int s1ap_send_e_rab_modification_confirm(mme_ue_t *mme_ue);
|
||||
|
||||
int s1ap_send_path_switch_ack(mme_ue_t *mme_ue);
|
||||
int s1ap_send_path_switch_ack(
|
||||
mme_ue_t *mme_ue, bool e_rab_to_switched_in_uplink_list);
|
||||
|
||||
int s1ap_send_handover_command(enb_ue_t *source_ue);
|
||||
int s1ap_send_handover_preparation_failure(
|
||||
|
|
|
@ -155,7 +155,7 @@ 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) \
|
||||
#define SGWC_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);
|
||||
|
|
|
@ -159,6 +159,37 @@ static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
int sgwc_gtp_send_create_session_response(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *xact)
|
||||
{
|
||||
int rv;
|
||||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(xact);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
||||
h.teid = sgwc_ue->mme_s11_teid;
|
||||
|
||||
pkbuf = sgwc_s11_build_create_session_response(h.type, sess);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int sgwc_gtp_send_downlink_data_notification(
|
||||
uint8_t cause_value, sgwc_bearer_t *bearer)
|
||||
{
|
||||
|
@ -169,8 +200,8 @@ int sgwc_gtp_send_downlink_data_notification(
|
|||
|
||||
ogs_gtp_xact_t *gtp_xact = NULL;
|
||||
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(bearer);
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@ extern "C" {
|
|||
int sgwc_gtp_open(void);
|
||||
void sgwc_gtp_close(void);
|
||||
|
||||
int sgwc_gtp_send_create_session_response(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
|
||||
int sgwc_gtp_send_downlink_data_notification(
|
||||
uint8_t cause_value, sgwc_bearer_t *bearer);
|
||||
|
||||
|
|
|
@ -202,6 +202,32 @@ static void bearer_timeout(ogs_pfcp_xact_t *xact, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
int sgwc_pfcp_send_bearer_to_modify_list(
|
||||
sgwc_sess_t *sess, ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *sxabuf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
|
||||
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_to_modify_list(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);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int sgwc_pfcp_send_session_establishment_request(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact, ogs_pkbuf_t *gtpbuf)
|
||||
{
|
||||
|
@ -212,10 +238,6 @@ int sgwc_pfcp_send_session_establishment_request(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
|
@ -225,6 +247,10 @@ int sgwc_pfcp_send_session_establishment_request(
|
|||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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);
|
||||
|
||||
|
@ -237,55 +263,7 @@ int sgwc_pfcp_send_session_establishment_request(
|
|||
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);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int sgwc_pfcp_send_sess_modification_request(
|
||||
int sgwc_pfcp_send_session_modification_request(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact,
|
||||
ogs_pkbuf_t *gtpbuf, uint64_t flags)
|
||||
{
|
||||
|
@ -294,13 +272,20 @@ int sgwc_pfcp_send_sess_modification_request(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
xact = sgwc_pfcp_xact_create(sess, gtp_xact, gtpbuf, flags);
|
||||
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;
|
||||
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_for_each(&sess->bearer_list, bearer)
|
||||
ogs_list_add(&xact->bearer_to_modify_list, &bearer->to_modify_node);
|
||||
|
||||
return sgwc_pfcp_xact_commit(xact);
|
||||
return sgwc_pfcp_send_bearer_to_modify_list(sess, xact);
|
||||
}
|
||||
|
||||
int sgwc_pfcp_send_bearer_modification_request(
|
||||
|
@ -333,7 +318,7 @@ int sgwc_pfcp_send_bearer_modification_request(
|
|||
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);
|
||||
sxabuf = sgwc_sxa_build_bearer_to_modify_list(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(sxabuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
|
||||
|
@ -355,10 +340,6 @@ int sgwc_pfcp_send_session_deletion_request(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||
h.seid = sess->sgwu_sxa_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
|
@ -368,6 +349,10 @@ int sgwc_pfcp_send_session_deletion_request(
|
|||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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);
|
||||
|
||||
|
|
|
@ -29,31 +29,19 @@ extern "C" {
|
|||
int sgwc_pfcp_open(void);
|
||||
void sgwc_pfcp_close(void);
|
||||
|
||||
int sgwc_pfcp_send_bearer_to_modify_list(
|
||||
sgwc_sess_t *sess, ogs_pfcp_xact_t *xact);
|
||||
|
||||
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(
|
||||
int sgwc_pfcp_send_session_modification_request(
|
||||
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);
|
||||
|
||||
int sgwc_pfcp_send_session_deletion_request(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *gtp_xact, ogs_pkbuf_t *gtpbuf);
|
||||
|
||||
|
|
|
@ -19,6 +19,118 @@
|
|||
|
||||
#include "s11-build.h"
|
||||
|
||||
ogs_pkbuf_t *sgwc_s11_build_create_session_response(
|
||||
uint8_t type, sgwc_sess_t *sess)
|
||||
{
|
||||
int rv, i;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
sgwc_tunnel_t *ul_tunnel = NULL;
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_create_session_response_t *rsp = NULL;
|
||||
|
||||
ogs_gtp2_cause_t cause;
|
||||
|
||||
ogs_gtp2_f_teid_t sgw_s11_teid;
|
||||
int len;
|
||||
|
||||
ogs_gtp2_cause_t bearer_cause[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_f_teid_t sgw_s1u_teid[OGS_BEARER_PER_UE];
|
||||
int sgw_s1u_len[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_f_teid_t pgw_s5u_teid[OGS_BEARER_PER_UE];
|
||||
int pgw_s5u_len[OGS_BEARER_PER_UE];
|
||||
|
||||
ogs_debug("[SGWC] Create Session Response");
|
||||
|
||||
ogs_assert(sess);
|
||||
sgwc_ue = sess->sgwc_ue;
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
|
||||
rsp = >p_message.create_session_response;
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
||||
/* Set Cause */
|
||||
memset(&cause, 0, sizeof(cause));
|
||||
rsp->cause.presence = 1;
|
||||
rsp->cause.len = sizeof(cause);
|
||||
rsp->cause.data = &cause;
|
||||
|
||||
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
/* Send Control Plane(UL) : SGW-S11 */
|
||||
memset(&sgw_s11_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s11_teid.interface_type = OGS_GTP2_F_TEID_S11_S4_SGW_GTP_C;
|
||||
sgw_s11_teid.teid = htobe32(sgwc_ue->sgw_s11_teid);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
ogs_gtp_self()->gtpc_addr, ogs_gtp_self()->gtpc_addr6,
|
||||
&sgw_s11_teid, &len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
rsp->sender_f_teid_for_control_plane.presence = 1;
|
||||
rsp->sender_f_teid_for_control_plane.data = &sgw_s11_teid;
|
||||
rsp->sender_f_teid_for_control_plane.len = len;
|
||||
|
||||
i = 0;
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
/* Bearer EBI */
|
||||
rsp->bearer_contexts_created[i].presence = 1;
|
||||
rsp->bearer_contexts_created[i].eps_bearer_id.presence = 1;
|
||||
rsp->bearer_contexts_created[i].eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
/* Bearer Cause */
|
||||
memset(&bearer_cause[i], 0, sizeof(bearer_cause[i]));
|
||||
rsp->bearer_contexts_created[i].cause.presence = 1;
|
||||
rsp->bearer_contexts_created[i].cause.len = sizeof(bearer_cause[i]);
|
||||
rsp->bearer_contexts_created[i].cause.data = &bearer_cause[i];
|
||||
bearer_cause[i].value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
/* Data Plane(UL) */
|
||||
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
||||
ogs_assert(ul_tunnel);
|
||||
|
||||
ogs_debug(" SGW_S1U_TEID[0x%x] PGW_S5U_TEID[0x%x]",
|
||||
ul_tunnel->local_teid, ul_tunnel->remote_teid);
|
||||
|
||||
/* Data Plane(UL) : SGW-S1U */
|
||||
memset(&sgw_s1u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s1u_teid[i].interface_type = ul_tunnel->interface_type;
|
||||
sgw_s1u_teid[i].teid = htobe32(ul_tunnel->local_teid);
|
||||
ogs_assert(ul_tunnel->local_addr || ul_tunnel->local_addr6);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
ul_tunnel->local_addr, ul_tunnel->local_addr6,
|
||||
&sgw_s1u_teid[i], &sgw_s1u_len[i]);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.data =
|
||||
&sgw_s1u_teid[i];
|
||||
rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.len =
|
||||
sgw_s1u_len[i];
|
||||
|
||||
/* Data Plane(UL) : PGW-S5U */
|
||||
memset(&pgw_s5u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
pgw_s5u_teid[i].interface_type = OGS_GTP2_F_TEID_S5_S8_PGW_GTP_U;
|
||||
pgw_s5u_teid[i].teid = htobe32(ul_tunnel->remote_teid);
|
||||
rv = ogs_gtp2_ip_to_f_teid(&ul_tunnel->remote_ip,
|
||||
&pgw_s5u_teid[i], &pgw_s5u_len[i]);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.data =
|
||||
&pgw_s5u_teid[i];
|
||||
rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.len =
|
||||
pgw_s5u_len[i];
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
gtp_message.h.type = type;
|
||||
return ogs_gtp2_build_msg(>p_message);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgwc_s11_build_downlink_data_notification(
|
||||
uint8_t cause_value, sgwc_bearer_t *bearer)
|
||||
{
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
ogs_pkbuf_t *sgwc_s11_build_create_session_response(
|
||||
uint8_t type, sgwc_sess_t *sess);
|
||||
|
||||
ogs_pkbuf_t *sgwc_s11_build_downlink_data_notification(
|
||||
uint8_t cause_value, sgwc_bearer_t *bearer);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "s11-handler.h"
|
||||
|
||||
static void sess_timeout(ogs_gtp_xact_t *xact, void *data)
|
||||
static void gtp_sess_timeout(ogs_gtp_xact_t *xact, void *data)
|
||||
{
|
||||
sgwc_sess_t *sess = data;
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
|
@ -52,7 +52,7 @@ static void sess_timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
||||
static void gtp_bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
||||
{
|
||||
sgwc_bearer_t *bearer = data;
|
||||
sgwc_sess_t *sess = NULL;
|
||||
|
@ -72,6 +72,29 @@ static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
|||
sgwc_ue->imsi_bcd, type);
|
||||
}
|
||||
|
||||
static void pfcp_sess_timeout(ogs_pfcp_xact_t *xact, void *data)
|
||||
{
|
||||
uint8_t type;
|
||||
|
||||
ogs_assert(xact);
|
||||
type = xact->seq[0].type;
|
||||
|
||||
switch (type) {
|
||||
case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE:
|
||||
ogs_error("No PFCP session establishment response");
|
||||
break;
|
||||
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
|
||||
ogs_error("No PFCP session modification response");
|
||||
break;
|
||||
case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE:
|
||||
ogs_error("No PFCP session deletion response");
|
||||
break;
|
||||
default:
|
||||
ogs_error("Not implemented [type:%d]", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* This code was created in case it will be used later,
|
||||
* and is currently not being used. */
|
||||
static uint8_t pfcp_cause_from_gtp(uint8_t gtp_cause)
|
||||
|
@ -116,6 +139,7 @@ void sgwc_s11_handle_create_session_request(
|
|||
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_xact,
|
||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||
{
|
||||
int i;
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
sgwc_sess_t *sess = NULL;
|
||||
|
@ -164,15 +188,15 @@ void sgwc_s11_handle_create_session_request(
|
|||
ogs_error("No IMSI");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.presence == 0) {
|
||||
if (req->bearer_contexts_to_be_created[0].presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.eps_bearer_id.presence == 0) {
|
||||
if (req->bearer_contexts_to_be_created[0].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.bearer_level_qos.presence == 0) {
|
||||
if (req->bearer_contexts_to_be_created[0].bearer_level_qos.presence == 0) {
|
||||
ogs_error("No Bearer QoS");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
@ -201,7 +225,7 @@ void sgwc_s11_handle_create_session_request(
|
|||
req->access_point_name.data,
|
||||
ogs_min(req->access_point_name.len, OGS_MAX_APN_LEN)));
|
||||
sess = sgwc_sess_find_by_ebi(sgwc_ue,
|
||||
req->bearer_contexts_to_be_created.eps_bearer_id.u8);
|
||||
req->bearer_contexts_to_be_created[0].eps_bearer_id.u8);
|
||||
if (sess) {
|
||||
ogs_info("OLD Session Release [IMSI:%s,APN:%s]",
|
||||
sgwc_ue->imsi_bcd, sess->session.name);
|
||||
|
@ -243,27 +267,100 @@ void sgwc_s11_handle_create_session_request(
|
|||
return;
|
||||
}
|
||||
|
||||
/* Set Bearer QoS */
|
||||
/* Remove all previous bearer */
|
||||
sgwc_bearer_remove_all(sess);
|
||||
|
||||
/* Setup Bearer */
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (req->bearer_contexts_to_be_created[i].presence == 0)
|
||||
break;
|
||||
if (req->bearer_contexts_to_be_created[i].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
break;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created[i].
|
||||
bearer_level_qos.presence == 0) {
|
||||
ogs_error("No Bearer QoS");
|
||||
break;
|
||||
}
|
||||
|
||||
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
&req->bearer_contexts_to_be_created.bearer_level_qos);
|
||||
ogs_assert(req->bearer_contexts_to_be_created.bearer_level_qos.len ==
|
||||
decoded);
|
||||
&req->bearer_contexts_to_be_created[i].bearer_level_qos);
|
||||
ogs_assert(decoded ==
|
||||
req->bearer_contexts_to_be_created[i].bearer_level_qos.len);
|
||||
|
||||
bearer = sgwc_bearer_add(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
/* Set Bearer EBI */
|
||||
bearer->ebi = req->bearer_contexts_to_be_created[i].eps_bearer_id.u8;
|
||||
|
||||
if (req->bearer_contexts_to_be_created[i].s1_u_enodeb_f_teid.presence) {
|
||||
|
||||
sgwc_tunnel_t *dl_tunnel = NULL;
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
ogs_gtp2_f_teid_t *enb_s1u_teid = NULL;
|
||||
|
||||
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
||||
ogs_assert(dl_tunnel);
|
||||
|
||||
/* Data Plane(DL) : eNB-S1U */
|
||||
enb_s1u_teid = req->bearer_contexts_to_be_created[i].
|
||||
s1_u_enodeb_f_teid.data;
|
||||
dl_tunnel->remote_teid = be32toh(enb_s1u_teid->teid);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(enb_s1u_teid, &dl_tunnel->remote_ip));
|
||||
|
||||
far = dl_tunnel->far;
|
||||
ogs_assert(far);
|
||||
|
||||
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
||||
|
||||
ogs_assert(OGS_OK == ogs_pfcp_ip_to_outer_header_creation(
|
||||
&dl_tunnel->remote_ip, &far->outer_header_creation,
|
||||
&far->outer_header_creation_len));
|
||||
far->outer_header_creation.teid = dl_tunnel->remote_teid;
|
||||
}
|
||||
|
||||
if (req->bearer_contexts_to_be_created[i].s5_s8_u_sgw_f_teid.presence) {
|
||||
|
||||
sgwc_tunnel_t *ul_tunnel = NULL;
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
||||
|
||||
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
||||
ogs_assert(ul_tunnel);
|
||||
|
||||
/* Data Plane(UL) : PGW-S5U */
|
||||
pgw_s5u_teid = req->bearer_contexts_to_be_created[i].
|
||||
s5_s8_u_sgw_f_teid.data;
|
||||
ul_tunnel->remote_teid = be32toh(pgw_s5u_teid->teid);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip));
|
||||
|
||||
far = ul_tunnel->far;
|
||||
ogs_assert(far);
|
||||
|
||||
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
||||
|
||||
ogs_assert(OGS_OK == ogs_pfcp_ip_to_outer_header_creation(
|
||||
&ul_tunnel->remote_ip, &far->outer_header_creation,
|
||||
&far->outer_header_creation_len));
|
||||
far->outer_header_creation.teid = ul_tunnel->remote_teid;
|
||||
}
|
||||
|
||||
/* Set Session QoS from Default Bearer Level QoS */
|
||||
if (i == 0) {
|
||||
sess->session.qos.index = bearer_qos.qci;
|
||||
sess->session.qos.arp.priority_level = bearer_qos.priority_level;
|
||||
sess->session.qos.arp.pre_emption_capability =
|
||||
bearer_qos.pre_emption_capability;
|
||||
sess->session.qos.arp.pre_emption_vulnerability =
|
||||
bearer_qos.pre_emption_vulnerability;
|
||||
|
||||
/* Remove all previous bearer */
|
||||
sgwc_bearer_remove_all(sess);
|
||||
|
||||
/* Setup Default Bearer */
|
||||
bearer = sgwc_bearer_add(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
/* Set Bearer EBI */
|
||||
bearer->ebi = req->bearer_contexts_to_be_created.eps_bearer_id.u8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive Control Plane(DL) : MME-S11 */
|
||||
mme_s11_teid = req->sender_f_teid_for_control_plane.data;
|
||||
|
@ -334,7 +431,7 @@ void sgwc_s11_handle_modify_bearer_request(
|
|||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
for (i = 0; i < 8 /* Max number of Bearer Contexts in Message */ ; i++) {
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
ogs_pfcp_xact_t *current_xact = NULL;
|
||||
|
||||
if (req->bearer_contexts_to_be_modified[i].presence == 0) {
|
||||
|
@ -372,10 +469,18 @@ void sgwc_s11_handle_modify_bearer_request(
|
|||
}
|
||||
|
||||
if (!current_xact) {
|
||||
current_xact = sgwc_pfcp_xact_create(sess, s11_xact, gtpbuf,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE);
|
||||
current_xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, pfcp_sess_timeout, sess);
|
||||
ogs_assert(current_xact);
|
||||
|
||||
current_xact->assoc_xact = s11_xact;
|
||||
current_xact->modify_flags = OGS_PFCP_MODIFY_SESSION|
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE;
|
||||
if (gtpbuf) {
|
||||
current_xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
||||
ogs_assert(current_xact->gtpbuf);
|
||||
}
|
||||
|
||||
ogs_list_add(&pfcp_xact_list, ¤t_xact->tmpnode);
|
||||
}
|
||||
|
||||
|
@ -453,7 +558,7 @@ void sgwc_s11_handle_modify_bearer_request(
|
|||
dl_tunnel->remote_teid, dl_tunnel->local_teid);
|
||||
|
||||
ogs_list_for_each_entry(&pfcp_xact_list, pfcp_xact, tmpnode)
|
||||
sgwc_pfcp_xact_commit(pfcp_xact);
|
||||
sgwc_pfcp_send_bearer_to_modify_list(pfcp_xact->data, pfcp_xact);
|
||||
}
|
||||
|
||||
void sgwc_s11_handle_delete_session_request(
|
||||
|
@ -465,6 +570,7 @@ void sgwc_s11_handle_delete_session_request(
|
|||
sgwc_sess_t *sess = NULL;
|
||||
ogs_gtp_xact_t *s5c_xact = NULL;
|
||||
ogs_gtp2_delete_session_request_t *req = NULL;
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
|
||||
ogs_assert(s11_xact);
|
||||
ogs_assert(gtpbuf);
|
||||
|
@ -505,6 +611,27 @@ void sgwc_s11_handle_delete_session_request(
|
|||
return;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
* Check Mandatory/Conditional IE Missing
|
||||
*****************************************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
if (req->indication_flags.presence &&
|
||||
req->indication_flags.data && req->indication_flags.len) {
|
||||
indication = req->indication_flags.data;
|
||||
}
|
||||
|
||||
if (indication &&
|
||||
indication->operation_indication == 1 &&
|
||||
indication->scope_indication == 1) {
|
||||
ogs_error("Invalid Indication");
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
||||
OGS_GTP2_CAUSE_INVALID_MESSAGE_FORMAT);
|
||||
return;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Check ALL Context
|
||||
********************/
|
||||
|
@ -516,6 +643,14 @@ void sgwc_s11_handle_delete_session_request(
|
|||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
|
||||
if (indication &&
|
||||
indication->operation_indication == 0 &&
|
||||
indication->scope_indication == 1) {
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_session_deletion_request(sess, s11_xact, gtpbuf));
|
||||
|
||||
} else {
|
||||
message->h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
||||
message->h.teid = sess->pgw_s5c_teid;
|
||||
|
||||
|
@ -523,7 +658,7 @@ void sgwc_s11_handle_delete_session_request(
|
|||
ogs_expect_or_return(gtpbuf);
|
||||
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &message->h, gtpbuf, sess_timeout, sess);
|
||||
sess->gnode, &message->h, gtpbuf, gtp_sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
|
||||
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
||||
|
@ -531,6 +666,7 @@ void sgwc_s11_handle_delete_session_request(
|
|||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void sgwc_s11_handle_create_bearer_response(
|
||||
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_xact,
|
||||
|
@ -1032,7 +1168,7 @@ void sgwc_s11_handle_release_access_bearers_request(
|
|||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_sess_modification_request(
|
||||
sgwc_pfcp_send_session_modification_request(
|
||||
sess, s11_xact, gtpbuf,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE));
|
||||
}
|
||||
|
@ -1224,7 +1360,7 @@ void sgwc_s11_handle_create_indirect_data_forwarding_tunnel_request(
|
|||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_sess_modification_request(
|
||||
sgwc_pfcp_send_session_modification_request(
|
||||
sess, s11_xact, gtpbuf,
|
||||
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE));
|
||||
}
|
||||
|
@ -1270,7 +1406,7 @@ void sgwc_s11_handle_delete_indirect_data_forwarding_tunnel_request(
|
|||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_sess_modification_request(
|
||||
sgwc_pfcp_send_session_modification_request(
|
||||
sess, s11_xact, gtpbuf,
|
||||
OGS_PFCP_MODIFY_INDIRECT| OGS_PFCP_MODIFY_REMOVE));
|
||||
}
|
||||
|
@ -1375,7 +1511,7 @@ void sgwc_s11_handle_bearer_resource_command(
|
|||
ogs_expect_or_return(pkbuf);
|
||||
|
||||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &message->h, pkbuf, bearer_timeout, bearer);
|
||||
sess->gnode, &message->h, pkbuf, gtp_bearer_timeout, bearer);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
|
||||
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
||||
|
|
|
@ -63,7 +63,7 @@ void sgwc_s5c_handle_create_session_response(
|
|||
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
||||
{
|
||||
int rv;
|
||||
int rv, i;
|
||||
uint8_t cause_value;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
|
||||
|
@ -106,25 +106,6 @@ void sgwc_s5c_handle_create_session_response(
|
|||
} 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
ogs_error("No Context for EPS Bearer ID[%d]",
|
||||
rsp->bearer_contexts_created.eps_bearer_id.u8);
|
||||
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -143,10 +124,6 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_error("No GTP TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.presence == 0) {
|
||||
ogs_error("No GTP TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
if (rsp->pdn_address_allocation.presence) {
|
||||
ogs_paa_t paa;
|
||||
|
||||
|
@ -165,11 +142,7 @@ void sgwc_s5c_handle_create_session_response(
|
|||
|
||||
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;
|
||||
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -184,7 +157,12 @@ void sgwc_s5c_handle_create_session_response(
|
|||
********************/
|
||||
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
||||
|
||||
cause = rsp->bearer_contexts_created.cause.data;
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (rsp->bearer_contexts_created[i].cause.presence == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
cause = rsp->bearer_contexts_created[i].cause.data;
|
||||
ogs_assert(cause);
|
||||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
|
@ -194,6 +172,7 @@ void sgwc_s5c_handle_create_session_response(
|
|||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cause = rsp->cause.data;
|
||||
ogs_assert(cause);
|
||||
|
@ -216,12 +195,44 @@ void sgwc_s5c_handle_create_session_response(
|
|||
********************/
|
||||
ogs_assert(sgwc_ue);
|
||||
ogs_assert(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
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]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (rsp->bearer_contexts_created[i].presence == 0) {
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.presence == 0) {
|
||||
ogs_error("No GTP TEID");
|
||||
break;
|
||||
}
|
||||
|
||||
/* EPS Bearer ID */
|
||||
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
||||
rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
||||
if (!bearer) {
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||
return;
|
||||
}
|
||||
|
||||
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
||||
ogs_assert(ul_tunnel);
|
||||
|
||||
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
||||
ul_tunnel->local_teid, ul_tunnel->remote_teid);
|
||||
|
||||
/* Receive Data Plane(UL) : PGW-S5U */
|
||||
pgw_s5u_teid = rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.data;
|
||||
pgw_s5u_teid = rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.data;
|
||||
ogs_assert(pgw_s5u_teid);
|
||||
ul_tunnel->remote_teid = be32toh(pgw_s5u_teid->teid);
|
||||
|
||||
|
@ -243,22 +254,16 @@ void sgwc_s5c_handle_create_session_response(
|
|||
ogs_pfcp_ip_to_outer_header_creation(&ul_tunnel->remote_ip,
|
||||
&far->outer_header_creation, &far->outer_header_creation_len));
|
||||
far->outer_header_creation.teid = ul_tunnel->remote_teid;
|
||||
}
|
||||
|
||||
/* Receive Control Plane(UL) : PGW-S5C */
|
||||
pgw_s5c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.data;
|
||||
ogs_assert(pgw_s5c_teid);
|
||||
sess->pgw_s5c_teid = be32toh(pgw_s5c_teid->teid);
|
||||
|
||||
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]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
||||
ul_tunnel->local_teid, ul_tunnel->remote_teid);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_bearer_modification_request(
|
||||
bearer, s11_xact, gtpbuf,
|
||||
sgwc_pfcp_send_session_modification_request(
|
||||
sess, s11_xact, gtpbuf,
|
||||
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_ACTIVATE));
|
||||
}
|
||||
|
||||
|
@ -371,6 +376,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
int rv;
|
||||
ogs_gtp2_cause_t *cause = NULL;
|
||||
uint8_t cause_value;
|
||||
int modify_action;
|
||||
|
||||
sgwc_ue_t *sgwc_ue = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
@ -390,6 +396,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
ogs_assert(s5c_xact);
|
||||
s11_xact = s5c_xact->assoc_xact;
|
||||
ogs_assert(s11_xact);
|
||||
modify_action = s5c_xact->modify_action;
|
||||
|
||||
rv = ogs_gtp_xact_commit(s5c_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
@ -408,6 +415,11 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
else
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||
|
@ -425,6 +437,11 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
}
|
||||
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
else
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||
|
@ -441,6 +458,11 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
cause_value = cause->value;
|
||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("GTP Failed [CAUSE:%d]", cause_value);
|
||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
else
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||
|
@ -458,6 +480,10 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
|
||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST) {
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_gtp_send_create_session_response(sess, s11_xact));
|
||||
} else {
|
||||
message->h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||
message->h.teid = sgwc_ue->mme_s11_teid;
|
||||
|
||||
|
@ -470,6 +496,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
|||
rv = ogs_gtp_xact_commit(s11_xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void sgwc_s5c_handle_create_bearer_request(
|
||||
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
||||
|
|
|
@ -145,18 +145,8 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
||||
/* Cause is not "Context not found" */
|
||||
sgwc_ue = sgwc_ue_find_by_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
if (sgwc_ue) {
|
||||
gnode = sgwc_ue->gnode;
|
||||
ogs_assert(gnode);
|
||||
} else {
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_receive(gnode, >p_message.h, >p_xact);
|
||||
if (rv != OGS_OK) {
|
||||
|
@ -164,6 +154,11 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
||||
/* Cause is not "Context not found" */
|
||||
sgwc_ue = sgwc_ue_find_by_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
switch(gtp_message.h.type) {
|
||||
case OGS_GTP2_ECHO_REQUEST_TYPE:
|
||||
sgwc_handle_echo_request(gtp_xact, >p_message.echo_request);
|
||||
|
@ -239,17 +234,8 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
||||
sess = sgwc_sess_find_by_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
if (sess) {
|
||||
gnode = sess->gnode;
|
||||
ogs_assert(gnode);
|
||||
} else {
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_receive(gnode, >p_message.h, >p_xact);
|
||||
if (rv != OGS_OK) {
|
||||
|
@ -257,6 +243,10 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e)
|
|||
break;
|
||||
}
|
||||
|
||||
if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) {
|
||||
sess = sgwc_sess_find_by_teid(gtp_message.h.teid);
|
||||
}
|
||||
|
||||
switch(gtp_message.h.type) {
|
||||
case OGS_GTP2_ECHO_REQUEST_TYPE:
|
||||
sgwc_handle_echo_request(gtp_xact, >p_message.echo_request);
|
||||
|
|
|
@ -105,7 +105,7 @@ ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request(
|
|||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
||||
ogs_pkbuf_t *sgwc_sxa_build_bearer_to_modify_list(
|
||||
uint8_t type, sgwc_sess_t *sess, ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
|
@ -135,12 +135,6 @@ ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
|||
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();
|
||||
}
|
||||
|
@ -166,6 +160,7 @@ ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
|||
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 =
|
||||
|
@ -193,6 +188,7 @@ ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
|||
ogs_assert_if_reached();
|
||||
|
||||
} else if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
|
||||
pdr = tunnel->pdr;
|
||||
if (pdr) {
|
||||
ogs_pfcp_build_create_pdr(
|
||||
|
@ -214,7 +210,10 @@ ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
|||
num_of_create_far++;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
} else if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
}
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
|
||||
far = tunnel->far;
|
||||
if (far) {
|
||||
ogs_pfcp_build_update_far_deactivate(
|
||||
|
@ -224,7 +223,9 @@ ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
|||
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) {
|
||||
|
@ -241,6 +242,7 @@ ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
|||
tunnel->far->smreq_flags.value = 0;
|
||||
} else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request(
|
||||
uint8_t type, sgwc_sess_t *sess);
|
||||
ogs_pkbuf_t *sgwc_sxa_build_session_modification_request(
|
||||
ogs_pkbuf_t *sgwc_sxa_build_bearer_to_modify_list(
|
||||
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);
|
||||
|
|
|
@ -134,10 +134,15 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
|
||||
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;
|
||||
int sgw_s5c_len;
|
||||
ogs_gtp2_f_teid_t sgw_s5c_teid;
|
||||
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
||||
|
||||
int i, num_of_sgw_s5u;
|
||||
uint8_t ebi[OGS_BEARER_PER_UE];
|
||||
int sgw_s5u_len[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_f_teid_t sgw_s5u_teid[OGS_BEARER_PER_UE];
|
||||
|
||||
ogs_gtp_xact_t *s11_xact = NULL, *s5c_xact = NULL;
|
||||
ogs_gtp_node_t *pgw = NULL;
|
||||
|
||||
|
@ -248,11 +253,20 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
bearer = sgwc_default_bearer_in_sess(sess);
|
||||
ogs_assert(bearer);
|
||||
ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||
|
||||
/* Data Plane(DL) : SGW-S5U */
|
||||
i = 0;
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
||||
ogs_assert(dl_tunnel);
|
||||
|
||||
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
||||
dl_tunnel->local_teid, dl_tunnel->remote_teid);
|
||||
|
||||
if (dl_tunnel->local_addr == NULL && dl_tunnel->local_addr6 == NULL) {
|
||||
ogs_error("No UP F-TEID");
|
||||
ogs_gtp_send_error_message(
|
||||
|
@ -262,10 +276,21 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
return;
|
||||
}
|
||||
|
||||
/* UP F-SEID */
|
||||
up_f_seid = pfcp_rsp->up_f_seid.data;
|
||||
ogs_assert(up_f_seid);
|
||||
sess->sgwu_sxa_seid = be64toh(up_f_seid->seid);
|
||||
ebi[i] = bearer->ebi;
|
||||
|
||||
memset(&sgw_s5u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s5u_teid[i].teid = htobe32(dl_tunnel->local_teid);
|
||||
sgw_s5u_teid[i].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[i], &sgw_s5u_len[i]);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
num_of_sgw_s5u = i;
|
||||
|
||||
/* Send Control Plane(DL) : SGW-S5C */
|
||||
memset(&sgw_s5c_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
|
@ -276,10 +301,10 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
&sgw_s5c_teid, &sgw_s5c_len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
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);
|
||||
/* UP F-SEID */
|
||||
up_f_seid = pfcp_rsp->up_f_seid.data;
|
||||
ogs_assert(up_f_seid);
|
||||
sess->sgwu_sxa_seid = be64toh(up_f_seid->seid);
|
||||
|
||||
pgw_s5c_teid = create_session_request->
|
||||
pgw_s5_s8_address_for_control_plane_or_pmip.data;
|
||||
|
@ -299,16 +324,6 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
/* Setup GTP Node */
|
||||
OGS_SETUP_GTP_NODE(sess, pgw);
|
||||
|
||||
/* 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, &sgw_s5u_len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
/* Check Indication */
|
||||
if (create_session_request->indication_flags.presence &&
|
||||
create_session_request->indication_flags.data &&
|
||||
|
@ -340,20 +355,24 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
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].
|
||||
for (i = 0; i < num_of_sgw_s5u; i++) {
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
||||
presence = 1;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
||||
eps_bearer_id.presence = 1;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
/* Bearer Context : EBI */
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
||||
eps_bearer_id.u8 = ebi[i];
|
||||
|
||||
/* Data Plane(DL) : SGW-S5U */
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[0].
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
||||
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;
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
||||
s4_u_sgsn_f_teid.data = &sgw_s5u_teid[i];
|
||||
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
||||
s4_u_sgsn_f_teid.len = sgw_s5u_len[i];
|
||||
}
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
@ -362,7 +381,11 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
s5c_xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &send_message.h, pkbuf, sess_timeout, sess);
|
||||
ogs_expect_or_return(s5c_xact);
|
||||
|
||||
s5c_xact->modify_action = OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST;
|
||||
|
||||
} else {
|
||||
|
||||
/* Create Session Request */
|
||||
recv_message->h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||
|
@ -379,12 +402,14 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
presence = 0;
|
||||
|
||||
/* Bearer Contexts */
|
||||
create_session_request->bearer_contexts_to_be_created.
|
||||
for (i = 0; i < num_of_sgw_s5u; i++) {
|
||||
create_session_request->bearer_contexts_to_be_created[i].
|
||||
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;
|
||||
create_session_request->bearer_contexts_to_be_created[i].
|
||||
s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid[i];
|
||||
create_session_request->bearer_contexts_to_be_created[i].
|
||||
s5_s8_u_sgw_f_teid.len = sgw_s5u_len[i];
|
||||
}
|
||||
|
||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
@ -617,7 +642,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
|
||||
sgwc_tunnel_t *tunnel = NULL, *next_tunnel = NULL;
|
||||
|
@ -702,9 +727,6 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
gtp_req = &recv_message->create_bearer_request;
|
||||
ogs_assert(gtp_req);
|
||||
|
||||
/* Remove S5U-F-TEID */
|
||||
gtp_req->bearer_contexts.s4_u_sgsn_f_teid.presence = 0;
|
||||
|
||||
/* Send Data Plane(UL) : SGW-S1U */
|
||||
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s1u_teid.interface_type = ul_tunnel->interface_type;
|
||||
|
@ -797,7 +819,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
|
||||
sgwc_tunnel_t *tunnel = NULL;
|
||||
|
@ -921,10 +943,12 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
|
||||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
|
||||
ogs_gtp2_create_session_response_t *gtp_rsp = NULL;
|
||||
ogs_gtp2_f_teid_t sgw_s11_teid;
|
||||
ogs_gtp2_f_teid_t sgw_s1u_teid;
|
||||
ogs_gtp2_f_teid_t sgw_s1u_teid[OGS_BEARER_PER_UE];
|
||||
int sgw_s1u_len[OGS_BEARER_PER_UE];
|
||||
|
||||
ogs_assert(recv_message);
|
||||
gtp_rsp = &recv_message->create_session_response;
|
||||
|
@ -943,19 +967,30 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
gtp_rsp->sender_f_teid_for_control_plane.len = len;
|
||||
|
||||
/* Send Data Plane(UL) : SGW-S1U */
|
||||
i = 0;
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
||||
ogs_assert(ul_tunnel);
|
||||
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s1u_teid.interface_type = ul_tunnel->interface_type;
|
||||
sgw_s1u_teid.teid = htobe32(ul_tunnel->local_teid);
|
||||
|
||||
memset(&sgw_s1u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
sgw_s1u_teid[i].interface_type = ul_tunnel->interface_type;
|
||||
sgw_s1u_teid[i].teid = htobe32(ul_tunnel->local_teid);
|
||||
ogs_assert(ul_tunnel->local_addr || ul_tunnel->local_addr6);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
ul_tunnel->local_addr, ul_tunnel->local_addr6,
|
||||
&sgw_s1u_teid, &len);
|
||||
&sgw_s1u_teid[i], &sgw_s1u_len[i]);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
gtp_rsp->bearer_contexts_created.s1_u_enodeb_f_teid.presence = 1;
|
||||
gtp_rsp->bearer_contexts_created.s1_u_enodeb_f_teid.data =
|
||||
&sgw_s1u_teid;
|
||||
gtp_rsp->bearer_contexts_created.s1_u_enodeb_f_teid.len = len;
|
||||
gtp_rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.
|
||||
presence = 1;
|
||||
gtp_rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.
|
||||
data = &sgw_s1u_teid[i];
|
||||
gtp_rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.
|
||||
len = sgw_s1u_len[i];
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
recv_message->h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
||||
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
||||
|
@ -970,10 +1005,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
||||
#if 0 /* FIXME */
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
#endif
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
if (SGWC_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;
|
||||
|
@ -1023,7 +1055,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
|
||||
/* Copy Bearer-Contexts-Modified from Modify-Bearer-Request
|
||||
*
|
||||
* TS 29.274 Table 7.2.7-2
|
||||
* TS 29.274 Table 7.2.8-2
|
||||
* NOTE 1: The SGW shall not change its F-TEID for a given interface
|
||||
* during the Handover, Service Request, E-UTRAN Initial Attach,
|
||||
* UE Requested PDN connectivity and PDP Context Activation procedures.
|
||||
|
@ -1083,12 +1115,10 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
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) {
|
||||
if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
|
||||
/* It's faked method for receiving `bearer` context */
|
||||
|
@ -1098,7 +1128,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_gtp_send_downlink_data_notification(
|
||||
|
@ -1112,7 +1142,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
ogs_pfcp_xact_commit(pfcp_xact);
|
||||
|
||||
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
||||
if (SESSION_SYNC_DONE(sgwc_ue,
|
||||
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
||||
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
||||
|
||||
ogs_gtp2_release_access_bearers_response_t *gtp_rsp = NULL;
|
||||
|
@ -1194,6 +1224,15 @@ void sgwc_sxa_handle_session_deletion_response(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (gtp_message->h.type == OGS_GTP2_DELETE_SESSION_REQUEST_TYPE) {
|
||||
/*
|
||||
* X2-based Handover with SGW change
|
||||
* 1. MME sends Delete Session Request to SGW-C
|
||||
* 2. SGW-C sends Delete Session Response to MME.
|
||||
*/
|
||||
gtp_message->h.type = OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE;
|
||||
}
|
||||
|
||||
switch (gtp_message->h.type) {
|
||||
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
|
||||
/*
|
||||
|
@ -1350,7 +1389,7 @@ void sgwc_sxa_handle_session_report_request(
|
|||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
sgwc_pfcp_send_sess_modification_request(sess,
|
||||
sgwc_pfcp_send_session_modification_request(sess,
|
||||
/* We only use the `assoc_xact` parameter temporarily here
|
||||
* to pass the `bearer` context. */
|
||||
(ogs_gtp_xact_t *)bearer,
|
||||
|
|
|
@ -133,7 +133,33 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
ogs_assert(ogs_pkbuf_pull(pkbuf, len));
|
||||
|
||||
if (gtp_h->type == OGS_GTPU_MSGTYPE_END_MARKER) {
|
||||
/* Nothing */
|
||||
ogs_pfcp_object_t *pfcp_object = NULL;
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
ogs_pkbuf_t *sendbuf = NULL;
|
||||
|
||||
pfcp_object = ogs_pfcp_object_find_by_teid(teid);
|
||||
if (!pfcp_object) {
|
||||
/* TODO : Send Error Indication */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
switch(pfcp_object->type) {
|
||||
case OGS_PFCP_OBJ_PDR_TYPE:
|
||||
pdr = (ogs_pfcp_pdr_t *)pfcp_object;
|
||||
ogs_assert(pdr);
|
||||
break;
|
||||
default:
|
||||
ogs_fatal("Unknown type [%d]", pfcp_object->type);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
ogs_assert(pdr);
|
||||
|
||||
sendbuf = ogs_pkbuf_copy(pkbuf);
|
||||
ogs_assert(sendbuf);
|
||||
|
||||
/* Forward packet */
|
||||
ogs_pfcp_send_g_pdu(pdr, gtp_h->type, sendbuf);
|
||||
|
||||
} else if (gtp_h->type == OGS_GTPU_MSGTYPE_ERR_IND) {
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
|
@ -209,7 +235,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
}
|
||||
|
||||
ogs_assert(pdr);
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(pdr, pkbuf, &report));
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(
|
||||
pdr, gtp_h->type, pkbuf, &report));
|
||||
|
||||
if (report.type.downlink_data_report) {
|
||||
ogs_assert(pdr->sess);
|
||||
|
|
|
@ -394,7 +394,7 @@ void smf_bearer_binding(smf_sess_t *sess)
|
|||
}
|
||||
}
|
||||
|
||||
int smf_gtp_send_create_bearer_request(smf_bearer_t *bearer)
|
||||
int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer)
|
||||
{
|
||||
int rv;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
void smf_bearer_binding(smf_sess_t *sess);
|
||||
int smf_gtp_send_create_bearer_request(smf_bearer_t *bearer);
|
||||
int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer);
|
||||
|
||||
void smf_qos_flow_binding(smf_sess_t *sess);
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ ED3(uint8_t spare:2;,
|
|||
typedef struct smf_bearer_s {
|
||||
ogs_lnode_t lnode; /**< A node of list_t */
|
||||
|
||||
ogs_lnode_t to_update_node;
|
||||
ogs_lnode_t to_modify_node;
|
||||
ogs_lnode_t to_delete_node;
|
||||
|
||||
uint32_t index;
|
||||
|
@ -391,6 +391,9 @@ typedef struct smf_sess_s {
|
|||
|
||||
ogs_list_t bearer_list;
|
||||
|
||||
ogs_list_t pdr_to_modify_list;
|
||||
ogs_list_t qos_flow_to_modify_list;
|
||||
|
||||
ogs_gtp_node_t *gnode;
|
||||
ogs_pfcp_node_t *pfcp_node;
|
||||
|
||||
|
|
|
@ -364,7 +364,7 @@ void smf_gn_handle_update_pdp_context_request(
|
|||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
}
|
||||
|
||||
/* User Plane(DL) : SGW-S5C */
|
||||
/* User Plane(DL) : SGW-S5U */
|
||||
bearer->sgw_s5u_teid = req->tunnel_endpoint_identifier_data_i.u32;
|
||||
rv = ogs_gtp1_gsn_addr_to_ip(req->sgsn_address_for_user_traffic.data,
|
||||
req->sgsn_address_for_user_traffic.len,
|
||||
|
@ -405,7 +405,7 @@ void smf_gn_handle_update_pdp_context_request(
|
|||
}
|
||||
}
|
||||
|
||||
rv = smf_epc_pfcp_send_session_modification_request(sess, xact,
|
||||
rv = smf_epc_pfcp_send_session_modification_request(sess, xact, NULL,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);
|
||||
|
|
|
@ -307,7 +307,7 @@ int gsm_handle_pdu_session_modification_request(
|
|||
|
||||
pfcp_flags |= OGS_PFCP_MODIFY_TFT_REPLACE;
|
||||
qos_flow_find_or_add(
|
||||
&update_list, qos_flow, to_update_node);
|
||||
&update_list, qos_flow, to_modify_node);
|
||||
|
||||
ogs_list_add(
|
||||
&qos_flow->pf_to_add_list, &pf->to_add_node);
|
||||
|
@ -389,7 +389,7 @@ int gsm_handle_pdu_session_modification_request(
|
|||
ogs_assert_if_reached();
|
||||
|
||||
qos_flow_find_or_add(
|
||||
&update_list, qos_flow, to_update_node);
|
||||
&update_list, qos_flow, to_modify_node);
|
||||
|
||||
ogs_list_add(
|
||||
&qos_flow->pf_to_add_list, &pf->to_add_node);
|
||||
|
@ -414,7 +414,7 @@ int gsm_handle_pdu_session_modification_request(
|
|||
if (ogs_list_count(&qos_flow->pf_list)) {
|
||||
pfcp_flags |= OGS_PFCP_MODIFY_TFT_DELETE;
|
||||
qos_flow_find_or_add(
|
||||
&update_list, qos_flow, to_update_node);
|
||||
&update_list, qos_flow, to_modify_node);
|
||||
} else {
|
||||
pfcp_flags |= OGS_PFCP_MODIFY_REMOVE;
|
||||
qos_flow_find_or_add(
|
||||
|
@ -469,7 +469,7 @@ int gsm_handle_pdu_session_modification_request(
|
|||
}
|
||||
|
||||
pfcp_flags |= OGS_PFCP_MODIFY_QOS_MODIFY;
|
||||
qos_flow_find_or_add(&update_list, qos_flow, to_update_node);
|
||||
qos_flow_find_or_add(&update_list, qos_flow, to_modify_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -303,10 +303,14 @@ void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
|
|||
}
|
||||
switch (gtp_xact->gtp_version) {
|
||||
case 1:
|
||||
ogs_assert(OGS_OK == smf_gtp1_send_create_pdp_context_response(sess, gtp_xact));
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_gtp1_send_create_pdp_context_response(
|
||||
sess, gtp_xact));
|
||||
break;
|
||||
case 2:
|
||||
ogs_assert(OGS_OK == smf_gtp_send_create_session_response(sess, gtp_xact));
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_gtp2_send_create_session_response(
|
||||
sess, gtp_xact));
|
||||
break;
|
||||
}
|
||||
if (sess->gtp_rat_type == OGS_GTP2_RAT_TYPE_WLAN) {
|
||||
|
@ -319,18 +323,10 @@ void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
|
|||
* PGW-C shall indicate PGW-U to stop counting and stop
|
||||
* forwarding downlink packets for the affected bearer(s).
|
||||
*/
|
||||
ogs_assert(sess->smf_ue);
|
||||
smf_sess_t *eutran_sess = smf_sess_find_by_apn(
|
||||
sess->smf_ue, sess->session.name, OGS_GTP2_RAT_TYPE_EUTRAN);
|
||||
if (eutran_sess) {
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_session_modification_request(
|
||||
eutran_sess, NULL,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
smf_epc_pfcp_send_deactivation(sess,
|
||||
OGS_GTP2_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP));
|
||||
}
|
||||
}
|
||||
smf_bearer_binding(sess);
|
||||
} else {
|
||||
#if 0
|
||||
|
@ -994,7 +990,7 @@ test_can_proceed:
|
|||
ogs_assert(OGS_OK == smf_gtp1_send_delete_pdp_context_response(sess, e->gtp_xact));
|
||||
break;
|
||||
case 2:
|
||||
ogs_assert(OGS_OK == smf_gtp_send_delete_session_response(sess, e->gtp_xact));
|
||||
ogs_assert(OGS_OK == smf_gtp2_send_delete_session_response(sess, e->gtp_xact));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -427,7 +427,7 @@ int smf_gtp1_send_update_pdp_context_response(
|
|||
return rv;
|
||||
}
|
||||
|
||||
int smf_gtp_send_create_session_response(
|
||||
int smf_gtp2_send_create_session_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact)
|
||||
{
|
||||
int rv;
|
||||
|
@ -453,7 +453,36 @@ int smf_gtp_send_create_session_response(
|
|||
return rv;
|
||||
}
|
||||
|
||||
int smf_gtp_send_delete_session_response(
|
||||
int smf_gtp2_send_modify_bearer_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||
ogs_gtp2_modify_bearer_request_t *req, bool sgw_relocation)
|
||||
{
|
||||
int rv;
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
ogs_assert(req);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||
h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
pkbuf = smf_s5c_build_modify_bearer_response(
|
||||
h.type, sess, req, sgw_relocation);
|
||||
ogs_expect_or_return_val(pkbuf, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int smf_gtp2_send_delete_session_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact)
|
||||
{
|
||||
int rv;
|
||||
|
@ -479,7 +508,7 @@ int smf_gtp_send_delete_session_response(
|
|||
return rv;
|
||||
}
|
||||
|
||||
int smf_gtp_send_delete_bearer_request(
|
||||
int smf_gtp2_send_delete_bearer_request(
|
||||
smf_bearer_t *bearer, uint8_t pti, uint8_t cause_value)
|
||||
{
|
||||
int rv;
|
||||
|
|
|
@ -38,12 +38,14 @@ int smf_gtp1_send_update_pdp_context_request(
|
|||
int smf_gtp1_send_update_pdp_context_response(
|
||||
smf_bearer_t *bearer, ogs_gtp_xact_t *xact);
|
||||
|
||||
int smf_gtp_send_create_session_response(
|
||||
int smf_gtp2_send_create_session_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
int smf_gtp_send_delete_session_response(
|
||||
int smf_gtp2_send_modify_bearer_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||
ogs_gtp2_modify_bearer_request_t *req, bool sgw_relocation);
|
||||
int smf_gtp2_send_delete_session_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
|
||||
int smf_gtp_send_delete_bearer_request(
|
||||
int smf_gtp2_send_delete_bearer_request(
|
||||
smf_bearer_t *bearer, uint8_t pti, uint8_t cause_value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -91,7 +91,7 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
|||
char buf[OGS_PLMNIDSTRLEN];
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_in6 sin6;
|
||||
uint32_t charing_id;
|
||||
uint32_t charging_id;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
|
@ -636,9 +636,9 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
|||
ogs_diam_gx_access_network_charging_identifier_value, 0,
|
||||
&avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
charing_id = htobe32(sess->charging.id);
|
||||
val.os.data = (uint8_t *)&charing_id;
|
||||
val.os.len = sizeof(charing_id);
|
||||
charging_id = htobe32(sess->charging.id);
|
||||
val.os.data = (uint8_t *)&charging_id;
|
||||
val.os.len = sizeof(charging_id);
|
||||
ret = fd_msg_avp_setvalue (avpch1, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
|
||||
|
|
|
@ -174,8 +174,8 @@ void smf_gy_handle_cca_update_request(
|
|||
/* Send PFCP Session Modification Request if we need to update the params. */
|
||||
if (modify_flags) {
|
||||
modify_flags |= OGS_PFCP_MODIFY_URR|OGS_PFCP_MODIFY_UL_ONLY;
|
||||
rv = smf_epc_pfcp_send_session_modification_request(sess, pfcp_xact,
|
||||
modify_flags,
|
||||
rv = smf_epc_pfcp_send_session_modification_request(
|
||||
sess, pfcp_xact, NULL, modify_flags,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
|
|
@ -110,7 +110,7 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request(
|
|||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
||||
ogs_pkbuf_t *smf_n4_build_pdr_to_modify_list(
|
||||
uint8_t type, smf_sess_t *sess, ogs_pfcp_xact_t *xact)
|
||||
{
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
@ -142,7 +142,7 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
|||
ogs_pfcp_pdrbuf_init();
|
||||
}
|
||||
|
||||
ogs_list_for_each(&sess->pfcp.pdr_list, pdr) {
|
||||
ogs_list_for_each_entry(&sess->pdr_to_modify_list, pdr, to_modify_node) {
|
||||
ogs_pfcp_far_t *far = pdr->far;
|
||||
ogs_assert(far);
|
||||
|
||||
|
@ -238,22 +238,29 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request(
|
|||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
||||
uint8_t type, smf_bearer_t *qos_flow, ogs_pfcp_xact_t *xact)
|
||||
ogs_pkbuf_t *smf_n4_build_qos_flow_to_modify_list(
|
||||
uint8_t type, smf_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;
|
||||
int i;
|
||||
|
||||
smf_sess_t *sess = NULL;
|
||||
smf_bearer_t *qos_flow = NULL;
|
||||
|
||||
int num_of_remove_pdr = 0;
|
||||
int num_of_remove_far = 0;
|
||||
int num_of_remove_qer = 0;
|
||||
int num_of_create_pdr = 0;
|
||||
int num_of_create_far = 0;
|
||||
int num_of_create_qer = 0;
|
||||
int num_of_update_pdr = 0;
|
||||
int num_of_update_far = 0;
|
||||
int num_of_update_qer = 0;
|
||||
|
||||
uint64_t modify_flags = 0;
|
||||
|
||||
ogs_debug("QoS Flow Modification Request");
|
||||
ogs_debug("Bearer Modification Request");
|
||||
|
||||
ogs_assert(qos_flow);
|
||||
sess = qos_flow->sess;
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
modify_flags = xact->modify_flags;
|
||||
|
@ -270,97 +277,104 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
|||
ogs_pfcp_pdrbuf_init();
|
||||
}
|
||||
|
||||
ogs_list_for_each_entry(
|
||||
&sess->qos_flow_to_modify_list, qos_flow, to_modify_node) {
|
||||
|
||||
if (modify_flags & OGS_PFCP_MODIFY_REMOVE) {
|
||||
/* Remove PDR */
|
||||
i = 0;
|
||||
if (qos_flow->dl_pdr) {
|
||||
ogs_pfcp_tlv_remove_pdr_t *message = &req->remove_pdr[i];
|
||||
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 = qos_flow->dl_pdr->id;
|
||||
i++;
|
||||
num_of_remove_pdr++;
|
||||
}
|
||||
if (qos_flow->ul_pdr) {
|
||||
ogs_pfcp_tlv_remove_pdr_t *message = &req->remove_pdr[i];
|
||||
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 = qos_flow->ul_pdr->id;
|
||||
i++;
|
||||
num_of_remove_pdr++;
|
||||
}
|
||||
|
||||
/* Remove FAR */
|
||||
i = 0;
|
||||
if (qos_flow->dl_far) {
|
||||
ogs_pfcp_tlv_remove_far_t *message = &req->remove_far[i];
|
||||
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 = qos_flow->dl_far->id;
|
||||
i++;
|
||||
num_of_remove_far++;
|
||||
}
|
||||
if (qos_flow->ul_far) {
|
||||
ogs_pfcp_tlv_remove_far_t *message = &req->remove_far[i];
|
||||
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 = qos_flow->ul_far->id;
|
||||
i++;
|
||||
num_of_remove_far++;
|
||||
}
|
||||
|
||||
/* Remove QER */
|
||||
i = 0;
|
||||
if (qos_flow->qer) {
|
||||
ogs_pfcp_tlv_remove_qer_t *message = &req->remove_qer[i];
|
||||
ogs_pfcp_tlv_remove_qer_t *message =
|
||||
&req->remove_qer[num_of_remove_qer];
|
||||
|
||||
message->presence = 1;
|
||||
message->qer_id.presence = 1;
|
||||
message->qer_id.u32 = qos_flow->qer->id;
|
||||
i++;
|
||||
num_of_remove_qer++;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (modify_flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
|
||||
/* Create PDR */
|
||||
i = 0;
|
||||
if (qos_flow->dl_pdr) {
|
||||
ogs_pfcp_build_create_pdr(
|
||||
&req->create_pdr[i], i, qos_flow->dl_pdr);
|
||||
i++;
|
||||
&req->create_pdr[num_of_create_pdr],
|
||||
num_of_create_pdr, qos_flow->dl_pdr);
|
||||
num_of_create_pdr++;
|
||||
|
||||
ogs_list_add(&xact->pdr_to_create_list,
|
||||
&qos_flow->dl_pdr->to_create_node);
|
||||
}
|
||||
if (qos_flow->ul_pdr) {
|
||||
ogs_pfcp_build_create_pdr(
|
||||
&req->create_pdr[i], i, qos_flow->ul_pdr);
|
||||
i++;
|
||||
&req->create_pdr[num_of_create_pdr],
|
||||
num_of_create_pdr, qos_flow->ul_pdr);
|
||||
num_of_create_pdr++;
|
||||
|
||||
ogs_list_add(&xact->pdr_to_create_list,
|
||||
&qos_flow->ul_pdr->to_create_node);
|
||||
}
|
||||
|
||||
/* Create FAR */
|
||||
i = 0;
|
||||
if (qos_flow->dl_far) {
|
||||
ogs_pfcp_build_create_far(
|
||||
&req->create_far[i], i, qos_flow->dl_far);
|
||||
i++;
|
||||
&req->create_far[num_of_create_far],
|
||||
num_of_create_far, qos_flow->dl_far);
|
||||
num_of_create_far++;
|
||||
}
|
||||
if (qos_flow->ul_far) {
|
||||
ogs_pfcp_build_create_far(
|
||||
&req->create_far[i], i, qos_flow->ul_far);
|
||||
i++;
|
||||
&req->create_far[num_of_create_far],
|
||||
num_of_create_far, qos_flow->ul_far);
|
||||
num_of_create_far++;
|
||||
}
|
||||
|
||||
/* Create QER */
|
||||
i = 0;
|
||||
if (qos_flow->qer) {
|
||||
ogs_pfcp_build_create_qer(
|
||||
&req->create_qer[i], i, qos_flow->qer);
|
||||
i++;
|
||||
&req->create_qer[num_of_create_qer],
|
||||
num_of_create_qer, qos_flow->qer);
|
||||
num_of_create_qer++;
|
||||
}
|
||||
}
|
||||
if (modify_flags &
|
||||
|
@ -369,22 +383,21 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
|||
OGS_PFCP_MODIFY_EPC_TFT_UPDATE)) {
|
||||
|
||||
/* Update PDR */
|
||||
i = 0;
|
||||
if (qos_flow->dl_pdr) {
|
||||
ogs_pfcp_build_update_pdr(
|
||||
&req->update_pdr[i], i, qos_flow->dl_pdr);
|
||||
i++;
|
||||
&req->update_pdr[num_of_update_pdr],
|
||||
num_of_update_pdr, qos_flow->dl_pdr);
|
||||
num_of_update_pdr++;
|
||||
}
|
||||
if (qos_flow->ul_pdr) {
|
||||
ogs_pfcp_build_update_pdr(
|
||||
&req->update_pdr[i], i, qos_flow->ul_pdr);
|
||||
i++;
|
||||
&req->update_pdr[num_of_update_pdr],
|
||||
num_of_update_pdr, qos_flow->ul_pdr);
|
||||
num_of_update_pdr++;
|
||||
}
|
||||
}
|
||||
if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE
|
||||
|| modify_flags & OGS_PFCP_MODIFY_UL_ONLY) {
|
||||
if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
/* Update FAR - Only DL */
|
||||
i = 0;
|
||||
if (qos_flow->dl_far) {
|
||||
if (qos_flow->dl_far->apply_action &
|
||||
OGS_PFCP_APPLY_ACTION_FORW) {
|
||||
|
@ -395,30 +408,32 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request(
|
|||
}
|
||||
|
||||
ogs_pfcp_build_update_far_activate(
|
||||
&req->update_far[i], i, qos_flow->dl_far);
|
||||
i++;
|
||||
&req->update_far[num_of_update_far],
|
||||
num_of_update_far, qos_flow->dl_far);
|
||||
num_of_update_far++;
|
||||
|
||||
/* Clear all FAR flags */
|
||||
qos_flow->dl_far->smreq_flags.value = 0;
|
||||
}
|
||||
}
|
||||
} else if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
i = 0;
|
||||
if (qos_flow->dl_far) {
|
||||
ogs_pfcp_build_update_far_deactivate(
|
||||
&req->update_far[i], i, qos_flow->dl_far);
|
||||
i++;
|
||||
&req->update_far[num_of_update_far],
|
||||
num_of_update_far, qos_flow->dl_far);
|
||||
num_of_update_far++;
|
||||
}
|
||||
}
|
||||
if (modify_flags &
|
||||
(OGS_PFCP_MODIFY_QOS_MODIFY|
|
||||
OGS_PFCP_MODIFY_EPC_QOS_UPDATE)) {
|
||||
/* Update QER */
|
||||
i = 0;
|
||||
if (qos_flow->qer) {
|
||||
ogs_pfcp_build_update_qer(
|
||||
&req->update_qer[i], i, qos_flow->qer);
|
||||
i++;
|
||||
&req->update_qer[num_of_update_qer],
|
||||
num_of_update_qer, qos_flow->qer);
|
||||
num_of_update_qer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@ 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(
|
||||
ogs_pkbuf_t *smf_n4_build_pdr_to_modify_list(
|
||||
uint8_t type, smf_sess_t *sess, ogs_pfcp_xact_t *xact);
|
||||
ogs_pkbuf_t *smf_n4_build_qos_flow_to_modify_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, ogs_pfcp_xact_t *xact);
|
||||
ogs_pkbuf_t *smf_n4_build_session_deletion_request(
|
||||
uint8_t type, smf_sess_t *sess);
|
||||
|
||||
|
|
|
@ -823,6 +823,7 @@ uint8_t smf_epc_n4_handle_session_establishment_response(
|
|||
|
||||
void smf_epc_n4_handle_session_modification_response(
|
||||
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
|
||||
ogs_gtp2_message_t *recv_message,
|
||||
ogs_pfcp_session_modification_response_t *rsp)
|
||||
{
|
||||
int i;
|
||||
|
@ -940,7 +941,7 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
|
||||
} else if (flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
ogs_assert(bearer);
|
||||
ogs_assert(OGS_OK == smf_gtp_send_create_bearer_request(bearer));
|
||||
ogs_assert(OGS_OK == smf_gtp2_send_create_bearer_request(bearer));
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
||||
/*
|
||||
|
@ -1013,7 +1014,7 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
ogs_assert(linked_bearer);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_gtp_send_delete_bearer_request(
|
||||
smf_gtp2_send_delete_bearer_request(
|
||||
linked_bearer, gtp_pti, gtp_cause));
|
||||
} else {
|
||||
/*
|
||||
|
@ -1034,7 +1035,7 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
ogs_assert(bearer);
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_gtp_send_delete_bearer_request(
|
||||
smf_gtp2_send_delete_bearer_request(
|
||||
bearer,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
gtp_cause));
|
||||
|
@ -1043,12 +1044,36 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
|
||||
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
if (gtp_xact) {
|
||||
|
||||
/* SMF send Update PDP Context Response (GTPv1C) to SGSN */
|
||||
if (gtp_xact->gtp_version == 1) {
|
||||
|
||||
bearer = gtp_xact->data;
|
||||
smf_gtp1_send_update_pdp_context_response(bearer, gtp_xact);
|
||||
|
||||
} else {
|
||||
/* TODO: SMF send Modify Bearer Response (GTPv2C) to SGWC */
|
||||
|
||||
/* SMF send Modify Bearer Response (GTPv2C) to SGW-C */
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
|
||||
ogs_assert(recv_message);
|
||||
ogs_gtp2_modify_bearer_request_t *gtp_req =
|
||||
&recv_message->modify_bearer_request;
|
||||
|
||||
ogs_assert(OGS_OK == smf_gtp2_send_modify_bearer_response(
|
||||
sess, gtp_xact, gtp_req, true));
|
||||
|
||||
/* Check if Handover from Non-3GPP to 3GPP */
|
||||
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) {
|
||||
ogs_assert(OGS_OK == smf_epc_pfcp_send_deactivation(sess,
|
||||
OGS_GTP2_CAUSE_ACCESS_CHANGED_FROM_NON_3GPP_TO_3GPP));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Nothing */
|
||||
|
|
|
@ -41,6 +41,7 @@ uint8_t smf_epc_n4_handle_session_establishment_response(
|
|||
ogs_pfcp_session_establishment_response_t *rsp);
|
||||
void smf_epc_n4_handle_session_modification_response(
|
||||
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
|
||||
ogs_gtp2_message_t *gtp2_message,
|
||||
ogs_pfcp_session_modification_response_t *rsp);
|
||||
uint8_t smf_epc_n4_handle_session_deletion_response(
|
||||
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
|
||||
|
|
|
@ -294,6 +294,41 @@ static void bearer_epc_timeout(ogs_pfcp_xact_t *xact, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
int smf_pfcp_send_modify_list(
|
||||
smf_sess_t *sess,
|
||||
ogs_pkbuf_t *(*modify_list)(
|
||||
uint8_t type, smf_sess_t *sess, ogs_pfcp_xact_t *xact),
|
||||
ogs_pfcp_xact_t *xact, ogs_time_t duration)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *n4buf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(xact);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = (*modify_list)(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);
|
||||
|
||||
return OGS_OK;
|
||||
} else {
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
int smf_5gc_pfcp_send_session_establishment_request(
|
||||
smf_sess_t *sess, ogs_sbi_stream_t *stream)
|
||||
{
|
||||
|
@ -305,15 +340,15 @@ int smf_5gc_pfcp_send_session_establishment_request(
|
|||
ogs_assert(sess);
|
||||
ogs_assert(stream);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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;
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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);
|
||||
|
||||
|
@ -331,48 +366,34 @@ int smf_5gc_pfcp_send_session_modification_request(
|
|||
uint64_t flags, ogs_time_t duration)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *n4buf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
if ((flags & OGS_PFCP_MODIFY_ERROR_INDICATION) == 0)
|
||||
ogs_assert(stream);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_MODIFICATION_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->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
|
||||
|
||||
n4buf = smf_n4_build_session_modification_request(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
ogs_list_init(&sess->pdr_to_modify_list);
|
||||
ogs_list_for_each(&sess->pfcp.pdr_list, pdr)
|
||||
ogs_list_add(&sess->pdr_to_modify_list, &pdr->to_modify_node);
|
||||
|
||||
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);
|
||||
|
||||
return OGS_OK;
|
||||
} else {
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
rv = smf_pfcp_send_modify_list(
|
||||
sess, smf_n4_build_pdr_to_modify_list, xact, duration);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
|
||||
ogs_sbi_stream_t *stream, uint64_t flags)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *n4buf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
|
@ -380,10 +401,6 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
|
|||
sess = qos_flow->sess;
|
||||
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;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, qos_flow_5gc_timeout, qos_flow);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
@ -391,13 +408,11 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
|
|||
xact->assoc_stream = stream;
|
||||
xact->modify_flags = flags;
|
||||
|
||||
n4buf = smf_n4_build_qos_flow_modification_request(h.type, qos_flow, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
ogs_list_init(&sess->qos_flow_to_modify_list);
|
||||
ogs_list_add(&sess->qos_flow_to_modify_list, &qos_flow->to_modify_node);
|
||||
|
||||
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);
|
||||
rv = smf_pfcp_send_modify_list(
|
||||
sess, smf_n4_build_qos_flow_to_modify_list, xact, 0);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
|
@ -414,16 +429,16 @@ int smf_5gc_pfcp_send_session_deletion_request(
|
|||
ogs_assert(sess);
|
||||
ogs_assert(trigger);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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;
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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);
|
||||
|
||||
|
@ -446,16 +461,16 @@ int smf_epc_pfcp_send_session_establishment_request(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
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;
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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);
|
||||
|
||||
|
@ -469,20 +484,15 @@ int smf_epc_pfcp_send_session_establishment_request(
|
|||
}
|
||||
|
||||
int smf_epc_pfcp_send_session_modification_request(
|
||||
smf_sess_t *sess, void *gtp_xact,
|
||||
smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf,
|
||||
uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *n4buf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
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;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
|
@ -492,14 +502,17 @@ int smf_epc_pfcp_send_session_modification_request(
|
|||
|
||||
xact->gtp_pti = gtp_pti;
|
||||
xact->gtp_cause = gtp_cause;
|
||||
if (gtpbuf) {
|
||||
xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
||||
ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR);
|
||||
}
|
||||
|
||||
n4buf = smf_n4_build_session_modification_request(h.type, sess, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
ogs_list_init(&sess->pdr_to_modify_list);
|
||||
ogs_list_for_each(&sess->pfcp.pdr_list, pdr)
|
||||
ogs_list_add(&sess->pdr_to_modify_list, &pdr->to_modify_node);
|
||||
|
||||
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);
|
||||
rv = smf_pfcp_send_modify_list(
|
||||
sess, smf_n4_build_pdr_to_modify_list, xact, 0);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
|
@ -510,8 +523,6 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause)
|
||||
{
|
||||
int rv;
|
||||
ogs_pkbuf_t *n4buf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
|
||||
|
@ -519,10 +530,6 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
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->upf_n4_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, bearer_epc_timeout, bearer);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
@ -534,13 +541,11 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
xact->gtp_pti = gtp_pti;
|
||||
xact->gtp_cause = gtp_cause;
|
||||
|
||||
n4buf = smf_n4_build_qos_flow_modification_request(h.type, bearer, xact);
|
||||
ogs_expect_or_return_val(n4buf, OGS_ERROR);
|
||||
ogs_list_init(&sess->qos_flow_to_modify_list);
|
||||
ogs_list_add(&sess->qos_flow_to_modify_list, &bearer->to_modify_node);
|
||||
|
||||
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);
|
||||
rv = smf_pfcp_send_modify_list(
|
||||
sess, smf_n4_build_qos_flow_to_modify_list, xact, 0);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
|
||||
return rv;
|
||||
|
@ -556,10 +561,6 @@ int smf_epc_pfcp_send_session_deletion_request(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_epc_timeout, sess);
|
||||
ogs_expect_or_return_val(xact, OGS_ERROR);
|
||||
|
||||
|
@ -588,6 +589,10 @@ int smf_epc_pfcp_send_session_deletion_request(
|
|||
*/
|
||||
xact->assoc_xact = gtp_xact;
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
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);
|
||||
|
||||
|
@ -600,6 +605,60 @@ int smf_epc_pfcp_send_session_deletion_request(
|
|||
return rv;
|
||||
}
|
||||
|
||||
int smf_epc_pfcp_send_deactivation(smf_sess_t *sess, uint8_t gtp_cause)
|
||||
{
|
||||
int rv;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_sess_t *eutran_sess = NULL, *wlan_sess = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
switch (gtp_cause) {
|
||||
case OGS_GTP2_CAUSE_ACCESS_CHANGED_FROM_NON_3GPP_TO_3GPP:
|
||||
/* Handover from Non-3GPP to 3GPP */
|
||||
wlan_sess = smf_sess_find_by_apn(
|
||||
smf_ue, sess->session.name, OGS_GTP2_RAT_TYPE_WLAN);
|
||||
ogs_expect_or_return_val(wlan_sess, OGS_ERROR);
|
||||
ogs_expect_or_return_val(
|
||||
ogs_list_first(&wlan_sess->bearer_list), OGS_ERROR);
|
||||
|
||||
/* Deactivate WLAN Session */
|
||||
rv = smf_epc_pfcp_send_session_modification_request(
|
||||
wlan_sess, NULL, NULL,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP2_CAUSE_ACCESS_CHANGED_FROM_NON_3GPP_TO_3GPP);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, rv);
|
||||
break;
|
||||
|
||||
case OGS_GTP2_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP:
|
||||
/* Handover from 3GPP to Non-3GPP */
|
||||
eutran_sess = smf_sess_find_by_apn(
|
||||
smf_ue, sess->session.name, OGS_GTP2_RAT_TYPE_EUTRAN);
|
||||
if (eutran_sess) {
|
||||
ogs_expect_or_return_val(
|
||||
ogs_list_first(&eutran_sess->bearer_list), OGS_ERROR);
|
||||
|
||||
/* Deactivate EUTRAN Session */
|
||||
rv = smf_epc_pfcp_send_session_modification_request(
|
||||
eutran_sess, NULL, NULL,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP2_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, rv);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_fatal("Invalid GTP-Cause[%d]", gtp_cause);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int smf_pfcp_send_session_report_response(
|
||||
ogs_pfcp_xact_t *xact, smf_sess_t *sess, uint8_t cause)
|
||||
{
|
||||
|
|
|
@ -29,20 +29,27 @@ extern "C" {
|
|||
int smf_pfcp_open(void);
|
||||
void smf_pfcp_close(void);
|
||||
|
||||
int smf_pfcp_send_modify_list(
|
||||
smf_sess_t *sess,
|
||||
ogs_pkbuf_t *(*modify_list)(
|
||||
uint8_t type, smf_sess_t *sess, ogs_pfcp_xact_t *xact),
|
||||
ogs_pfcp_xact_t *xact, ogs_time_t duration);
|
||||
|
||||
int smf_5gc_pfcp_send_session_establishment_request(
|
||||
smf_sess_t *sess, ogs_sbi_stream_t *stream);
|
||||
int smf_5gc_pfcp_send_session_modification_request(
|
||||
smf_sess_t *sess, ogs_sbi_stream_t *stream,
|
||||
uint64_t flags, ogs_time_t duration);
|
||||
int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow,
|
||||
ogs_sbi_stream_t *stream, uint64_t flags);
|
||||
int smf_5gc_pfcp_send_qos_flow_modification_request(
|
||||
smf_bearer_t *qos_flow, ogs_sbi_stream_t *stream,
|
||||
uint64_t flags);
|
||||
int smf_5gc_pfcp_send_session_deletion_request(
|
||||
smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger);
|
||||
|
||||
int smf_epc_pfcp_send_session_establishment_request(
|
||||
smf_sess_t *sess, void *gtp_xact);
|
||||
int smf_epc_pfcp_send_session_modification_request(
|
||||
smf_sess_t *sess, void *gtp_xact,
|
||||
smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf,
|
||||
uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause);
|
||||
int smf_epc_pfcp_send_bearer_modification_request(
|
||||
smf_bearer_t *bearer, void *gtp_xact,
|
||||
|
@ -50,6 +57,8 @@ int smf_epc_pfcp_send_bearer_modification_request(
|
|||
int smf_epc_pfcp_send_session_deletion_request(
|
||||
smf_sess_t *sess, void *gtp_xact);
|
||||
|
||||
int smf_epc_pfcp_send_deactivation(smf_sess_t *sess, uint8_t gtp_cause);
|
||||
|
||||
int smf_pfcp_send_session_report_response(
|
||||
ogs_pfcp_xact_t *xact, smf_sess_t *sess, uint8_t cause);
|
||||
|
||||
|
|
|
@ -238,7 +238,8 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
|||
|
||||
if (xact->epc)
|
||||
smf_epc_n4_handle_session_modification_response(
|
||||
sess, xact, &message->pfcp_session_modification_response);
|
||||
sess, xact, e->gtp2_message,
|
||||
&message->pfcp_session_modification_response);
|
||||
else
|
||||
smf_5gc_n4_handle_session_modification_response(
|
||||
sess, xact, &message->pfcp_session_modification_response);
|
||||
|
|
|
@ -32,11 +32,16 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
|||
ogs_gtp2_create_session_response_t *rsp = NULL;
|
||||
|
||||
ogs_gtp2_cause_t cause;
|
||||
ogs_gtp2_cause_t bearer_cause;
|
||||
ogs_gtp2_f_teid_t smf_s5c_teid, pgw_s5u_teid;
|
||||
|
||||
int i;
|
||||
ogs_gtp2_cause_t bearer_cause[OGS_BEARER_PER_UE];
|
||||
ogs_gtp2_f_teid_t pgw_s5u_teid[OGS_BEARER_PER_UE];
|
||||
int pgw_s5u_len[OGS_BEARER_PER_UE];
|
||||
|
||||
ogs_gtp2_f_teid_t smf_s5c_teid;
|
||||
ogs_gtp2_ambr_t ambr;
|
||||
ogs_gtp2_bearer_qos_t bearer_qos;
|
||||
char bearer_qos_buf[GTP2_BEARER_QOS_LEN];
|
||||
char bearer_qos_buf[OGS_BEARER_PER_UE][GTP2_BEARER_QOS_LEN];
|
||||
int len;
|
||||
uint8_t pco_buf[OGS_MAX_PCO_LEN];
|
||||
int16_t pco_len;
|
||||
|
@ -44,13 +49,9 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
|||
ogs_debug("[SMF] Create Session Response");
|
||||
|
||||
ogs_assert(sess);
|
||||
bearer = smf_default_bearer_in_sess(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(" SGW_S5U_TEID[0x%x] PGW_S5U_TEID[0x%x]",
|
||||
bearer->sgw_s5u_teid, bearer->pgw_s5u_teid);
|
||||
|
||||
rsp = >p_message.create_session_response;
|
||||
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
||||
|
@ -137,17 +138,24 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
|||
rsp->protocol_configuration_options.len = pco_len;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
ogs_debug(" SGW_S5U_TEID[0x%x] PGW_S5U_TEID[0x%x]",
|
||||
bearer->sgw_s5u_teid, bearer->pgw_s5u_teid);
|
||||
|
||||
/* Bearer EBI */
|
||||
rsp->bearer_contexts_created.presence = 1;
|
||||
rsp->bearer_contexts_created.eps_bearer_id.presence = 1;
|
||||
rsp->bearer_contexts_created.eps_bearer_id.u8 = bearer->ebi;
|
||||
rsp->bearer_contexts_created[i].presence = 1;
|
||||
rsp->bearer_contexts_created[i].eps_bearer_id.presence = 1;
|
||||
rsp->bearer_contexts_created[i].eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
/* Bearer Cause */
|
||||
memset(&bearer_cause, 0, sizeof(bearer_cause));
|
||||
rsp->bearer_contexts_created.cause.presence = 1;
|
||||
rsp->bearer_contexts_created.cause.len = sizeof(bearer_cause);
|
||||
rsp->bearer_contexts_created.cause.data = &bearer_cause;
|
||||
bearer_cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
memset(&bearer_cause[i], 0, sizeof(bearer_cause[i]));
|
||||
rsp->bearer_contexts_created[i].cause.presence = 1;
|
||||
rsp->bearer_contexts_created[i].cause.len = sizeof(bearer_cause[i]);
|
||||
rsp->bearer_contexts_created[i].cause.data = &bearer_cause[i];
|
||||
bearer_cause[i].value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
/* Bearer QoS
|
||||
* if PCRF changes Bearer QoS, this should be included. */
|
||||
|
@ -160,41 +168,50 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
|||
bearer_qos.pre_emption_vulnerability =
|
||||
sess->session.qos.arp.pre_emption_vulnerability;
|
||||
|
||||
rsp->bearer_contexts_created.bearer_level_qos.presence = 1;
|
||||
ogs_gtp2_build_bearer_qos(&rsp->bearer_contexts_created.bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf, GTP2_BEARER_QOS_LEN);
|
||||
rsp->bearer_contexts_created[i].bearer_level_qos.presence = 1;
|
||||
ogs_gtp2_build_bearer_qos(
|
||||
&rsp->bearer_contexts_created[i].bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf[i], GTP2_BEARER_QOS_LEN);
|
||||
}
|
||||
|
||||
/* Bearer Charging ID */
|
||||
rsp->bearer_contexts_created.charging_id.presence = 1;
|
||||
rsp->bearer_contexts_created.charging_id.u32 = sess->charging.id;
|
||||
rsp->bearer_contexts_created[i].charging_id.presence = 1;
|
||||
rsp->bearer_contexts_created[i].charging_id.u32 = sess->charging.id;
|
||||
|
||||
/* Data Plane(UL) : SMF-S5U */
|
||||
memset(&pgw_s5u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
pgw_s5u_teid.teid = htobe32(bearer->pgw_s5u_teid);
|
||||
memset(&pgw_s5u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
pgw_s5u_teid[i].teid = htobe32(bearer->pgw_s5u_teid);
|
||||
ogs_assert(bearer->pgw_s5u_addr || bearer->pgw_s5u_addr6);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6, &pgw_s5u_teid, &len);
|
||||
bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6,
|
||||
&pgw_s5u_teid[i], &pgw_s5u_len[i]);
|
||||
ogs_expect_or_return_val(rv == OGS_OK, NULL);
|
||||
|
||||
switch (sess->gtp_rat_type) {
|
||||
case OGS_GTP2_RAT_TYPE_EUTRAN:
|
||||
pgw_s5u_teid.interface_type = OGS_GTP2_F_TEID_S5_S8_PGW_GTP_U;
|
||||
rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.data = &pgw_s5u_teid;
|
||||
rsp->bearer_contexts_created.s5_s8_u_sgw_f_teid.len = len;
|
||||
pgw_s5u_teid[i].interface_type = OGS_GTP2_F_TEID_S5_S8_PGW_GTP_U;
|
||||
rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.data =
|
||||
&pgw_s5u_teid[i];
|
||||
rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.len =
|
||||
pgw_s5u_len[i];
|
||||
break;
|
||||
case OGS_GTP2_RAT_TYPE_WLAN:
|
||||
pgw_s5u_teid.interface_type = OGS_GTP2_F_TEID_S2B_U_PGW_GTP_U;
|
||||
rsp->bearer_contexts_created.s12_rnc_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_created.s12_rnc_f_teid.data = &pgw_s5u_teid;
|
||||
rsp->bearer_contexts_created.s12_rnc_f_teid.len = len;
|
||||
pgw_s5u_teid[i].interface_type = OGS_GTP2_F_TEID_S2B_U_PGW_GTP_U;
|
||||
rsp->bearer_contexts_created[i].s12_rnc_f_teid.presence = 1;
|
||||
rsp->bearer_contexts_created[i].s12_rnc_f_teid.data =
|
||||
&pgw_s5u_teid[i];
|
||||
rsp->bearer_contexts_created[i].s12_rnc_f_teid.len =
|
||||
pgw_s5u_len[i];
|
||||
break;
|
||||
default:
|
||||
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
|
||||
ogs_assert_if_reached();
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
gtp_message.h.type = type;
|
||||
return ogs_gtp2_build_msg(>p_message);
|
||||
}
|
||||
|
@ -243,14 +260,21 @@ ogs_pkbuf_t *smf_s5c_build_delete_session_response(
|
|||
|
||||
ogs_pkbuf_t *smf_s5c_build_modify_bearer_response(
|
||||
uint8_t type, smf_sess_t *sess,
|
||||
ogs_gtp2_modify_bearer_request_t *req)
|
||||
ogs_gtp2_modify_bearer_request_t *req, bool sgw_relocation)
|
||||
{
|
||||
int i;
|
||||
|
||||
ogs_gtp2_message_t gtp_message;
|
||||
ogs_gtp2_modify_bearer_response_t *rsp = NULL;
|
||||
|
||||
ogs_gtp2_cause_t cause;
|
||||
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
ogs_assert(req);
|
||||
|
||||
rsp = >p_message.modify_bearer_response;
|
||||
|
@ -263,19 +287,42 @@ ogs_pkbuf_t *smf_s5c_build_modify_bearer_response(
|
|||
rsp->cause.data = &cause;
|
||||
rsp->cause.len = sizeof(cause);
|
||||
|
||||
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;
|
||||
if (sgw_relocation == true) {
|
||||
|
||||
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;
|
||||
if (smf_ue->msisdn_len) {
|
||||
rsp->msisdn.presence = 1;
|
||||
rsp->msisdn.len = smf_ue->msisdn_len;
|
||||
rsp->msisdn.data = smf_ue->msisdn;
|
||||
}
|
||||
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (req->bearer_contexts_to_be_modified[i].presence == 0)
|
||||
break;
|
||||
if (req->bearer_contexts_to_be_modified[i].
|
||||
eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
break;
|
||||
}
|
||||
|
||||
bearer = smf_bearer_find_by_ebi(sess,
|
||||
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8);
|
||||
if (!bearer) {
|
||||
ogs_error("Unknown EPS Bearer ID[%d]",
|
||||
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8);
|
||||
break;
|
||||
}
|
||||
|
||||
rsp->bearer_contexts_modified[i].presence = 1;
|
||||
rsp->bearer_contexts_modified[i].eps_bearer_id.presence = 1;
|
||||
rsp->bearer_contexts_modified[i].eps_bearer_id.u8 =
|
||||
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8;
|
||||
|
||||
rsp->bearer_contexts_modified[i].charging_id.presence = 1;
|
||||
rsp->bearer_contexts_modified[i].charging_id.u32 =
|
||||
sess->charging.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* build */
|
||||
gtp_message.h.type = type;
|
||||
|
|
|
@ -33,7 +33,7 @@ ogs_pkbuf_t *smf_s5c_build_delete_session_response(
|
|||
|
||||
ogs_pkbuf_t *smf_s5c_build_modify_bearer_response(
|
||||
uint8_t type, smf_sess_t *sess,
|
||||
ogs_gtp2_modify_bearer_request_t *req);
|
||||
ogs_gtp2_modify_bearer_request_t *req, bool sgw_relocation);
|
||||
|
||||
ogs_pkbuf_t *smf_s5c_build_create_bearer_request(
|
||||
uint8_t type, smf_bearer_t *bearer, ogs_gtp2_tft_t *tft);
|
||||
|
|
|
@ -52,7 +52,7 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
char buf1[OGS_ADDRSTRLEN];
|
||||
char buf2[OGS_ADDRSTRLEN];
|
||||
|
||||
int rv;
|
||||
int i, rv;
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
ogs_gtp2_uli_t uli;
|
||||
|
@ -82,15 +82,15 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
ogs_error("No TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.presence == 0) {
|
||||
if (req->bearer_contexts_to_be_created[0].presence == 0) {
|
||||
ogs_error("No Bearer");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.eps_bearer_id.presence == 0) {
|
||||
if (req->bearer_contexts_to_be_created[0].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.bearer_level_qos.presence == 0) {
|
||||
if (req->bearer_contexts_to_be_created[0].bearer_level_qos.presence == 0) {
|
||||
ogs_error("No EPS Bearer QoS");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
}
|
||||
switch (sess->gtp_rat_type) {
|
||||
case OGS_GTP2_RAT_TYPE_EUTRAN:
|
||||
if (req->bearer_contexts_to_be_created.
|
||||
if (req->bearer_contexts_to_be_created[0].
|
||||
s5_s8_u_sgw_f_teid.presence == 0) {
|
||||
ogs_error("No S5/S8 SGW GTP-U TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
@ -133,7 +133,7 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
ogs_error("No S6b Diameter Peer");
|
||||
cause_value = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created.
|
||||
if (req->bearer_contexts_to_be_created[0].
|
||||
s2b_u_epdg_f_teid_5.presence == 0) {
|
||||
ogs_error("No S2b ePDG GTP-U TEID");
|
||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||
|
@ -248,16 +248,34 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
/* Remove all previous bearer */
|
||||
smf_bearer_remove_all(sess);
|
||||
|
||||
/* Setup Default Bearer */
|
||||
/* Setup Bearer */
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (req->bearer_contexts_to_be_created[i].presence == 0)
|
||||
break;
|
||||
if (req->bearer_contexts_to_be_created[i].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
break;
|
||||
}
|
||||
if (req->bearer_contexts_to_be_created[i].
|
||||
bearer_level_qos.presence == 0) {
|
||||
ogs_error("No Bearer QoS");
|
||||
break;
|
||||
}
|
||||
|
||||
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
&req->bearer_contexts_to_be_created[i].bearer_level_qos);
|
||||
ogs_assert(decoded ==
|
||||
req->bearer_contexts_to_be_created[i].bearer_level_qos.len);
|
||||
|
||||
bearer = smf_bearer_add(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
/* Set Bearer EBI */
|
||||
bearer->ebi = req->bearer_contexts_to_be_created.eps_bearer_id.u8;
|
||||
bearer->ebi = req->bearer_contexts_to_be_created[i].eps_bearer_id.u8;
|
||||
|
||||
switch (sess->gtp_rat_type) {
|
||||
case OGS_GTP2_RAT_TYPE_EUTRAN:
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created.
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created[i].
|
||||
s5_s8_u_sgw_f_teid.data;
|
||||
ogs_assert(sgw_s5u_teid);
|
||||
bearer->sgw_s5u_teid = be32toh(sgw_s5u_teid->teid);
|
||||
|
@ -266,7 +284,7 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
|
||||
break;
|
||||
case OGS_GTP2_RAT_TYPE_WLAN:
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created.
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created[i].
|
||||
s2b_u_epdg_f_teid_5.data;
|
||||
ogs_assert(sgw_s5u_teid);
|
||||
bearer->sgw_s5u_teid = be32toh(sgw_s5u_teid->teid);
|
||||
|
@ -281,17 +299,16 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
ogs_debug(" SGW_S5U_TEID[0x%x] PGW_S5U_TEID[0x%x]",
|
||||
bearer->sgw_s5u_teid, bearer->pgw_s5u_teid);
|
||||
|
||||
/* Set Bearer QoS */
|
||||
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
&req->bearer_contexts_to_be_created.bearer_level_qos);
|
||||
ogs_assert(req->bearer_contexts_to_be_created.bearer_level_qos.len ==
|
||||
decoded);
|
||||
/* Set Session QoS from Default Bearer Level QoS */
|
||||
if (i == 0) {
|
||||
sess->session.qos.index = bearer_qos.qci;
|
||||
sess->session.qos.arp.priority_level = bearer_qos.priority_level;
|
||||
sess->session.qos.arp.pre_emption_capability =
|
||||
bearer_qos.pre_emption_capability;
|
||||
sess->session.qos.arp.pre_emption_vulnerability =
|
||||
bearer_qos.pre_emption_vulnerability;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set AMBR if available */
|
||||
if (req->aggregate_maximum_bit_rate.presence) {
|
||||
|
@ -324,6 +341,15 @@ uint8_t smf_s5c_handle_create_session_request(
|
|||
OGS_TLV_STORE_DATA(&sess->gtp.ue_timezone, &req->ue_time_zone);
|
||||
}
|
||||
|
||||
/* Set MSISDN */
|
||||
if (req->msisdn.presence && req->msisdn.len && req->msisdn.data) {
|
||||
smf_ue->msisdn_len = req->msisdn.len;
|
||||
memcpy(smf_ue->msisdn, req->msisdn.data,
|
||||
ogs_min(smf_ue->msisdn_len, OGS_MAX_MSISDN_LEN));
|
||||
ogs_buffer_to_bcd(smf_ue->msisdn,
|
||||
smf_ue->msisdn_len, smf_ue->msisdn_bcd);
|
||||
}
|
||||
|
||||
return OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
||||
}
|
||||
|
||||
|
@ -356,17 +382,14 @@ uint8_t smf_s5c_handle_delete_session_request(
|
|||
|
||||
void smf_s5c_handle_modify_bearer_request(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||
ogs_gtp2_modify_bearer_request_t *req)
|
||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_modify_bearer_request_t *req)
|
||||
{
|
||||
int rv;
|
||||
int rv, i;
|
||||
uint8_t cause_value = 0;
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
|
||||
ogs_gtp2_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
uint64_t flags = 0;
|
||||
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_sess_t *wlan_sess = NULL;
|
||||
smf_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_debug("Modify Bearer Request");
|
||||
|
||||
|
@ -405,50 +428,99 @@ void smf_s5c_handle_modify_bearer_request(
|
|||
rv = ogs_gtp2_f_teid_to_ip(sgw_s5c_teid, &sess->sgw_s5c_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
OGS_SETUP_GTP_NODE(sess, xact->gnode);
|
||||
|
||||
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);
|
||||
/* Check Modify Bearer */
|
||||
ogs_list_init(&sess->qos_flow_to_modify_list);
|
||||
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (req->bearer_contexts_to_be_modified[i].presence == 0)
|
||||
break;
|
||||
case OGS_GTP2_RAT_TYPE_WLAN:
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_created.
|
||||
s2b_u_epdg_f_teid_5.data;
|
||||
if (req->bearer_contexts_to_be_modified[i].
|
||||
eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EPS Bearer ID");
|
||||
break;
|
||||
}
|
||||
/* EPS Bearer ID */
|
||||
bearer = smf_bearer_find_by_ebi(sess,
|
||||
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8);
|
||||
if (!bearer) {
|
||||
ogs_error("No Bearer Context");
|
||||
break;
|
||||
}
|
||||
|
||||
if (req->bearer_contexts_to_be_modified[i].s4_u_sgsn_f_teid.presence) {
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
ogs_gtp2_f_teid_t *sgw_s5u_teid = NULL;
|
||||
|
||||
ogs_ip_t remote_ip;
|
||||
ogs_ip_t zero_ip;
|
||||
|
||||
/* Data Plane(DL) : SGW-S5U */
|
||||
sgw_s5u_teid = req->bearer_contexts_to_be_modified[i].
|
||||
s4_u_sgsn_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;
|
||||
default:
|
||||
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
|
||||
ogs_assert_if_reached();
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(sgw_s5u_teid, &remote_ip));
|
||||
|
||||
memset(&zero_ip, 0, sizeof(ogs_ip_t));
|
||||
if (memcmp(&bearer->sgw_s5u_ip, &zero_ip, sizeof(ogs_ip_t)) != 0 &&
|
||||
memcmp(&bearer->sgw_s5u_ip,
|
||||
&remote_ip, sizeof(ogs_ip_t)) != 0) {
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
|
||||
/* eNB IP is changed during handover */
|
||||
if (sess->pfcp_node->up_function_features.empu) {
|
||||
flags |= OGS_PFCP_MODIFY_END_MARKER;
|
||||
} else {
|
||||
ogs_error("UPF does not support End Marker");
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&bearer->sgw_s5u_ip, &remote_ip, sizeof(ogs_ip_t));
|
||||
|
||||
far = bearer->dl_far;
|
||||
ogs_assert(far);
|
||||
|
||||
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_pfcp_ip_to_outer_header_creation(
|
||||
&bearer->sgw_s5u_ip,
|
||||
&far->outer_header_creation,
|
||||
&far->outer_header_creation_len));
|
||||
far->outer_header_creation.teid = bearer->sgw_s5u_teid;
|
||||
|
||||
ogs_list_add(&sess->qos_flow_to_modify_list,
|
||||
&bearer->to_modify_node);
|
||||
|
||||
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;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
if (ogs_list_count(&sess->qos_flow_to_modify_list)) {
|
||||
|
||||
pkbuf = smf_s5c_build_modify_bearer_response(h.type, sess, req);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
/* Need to modify SGW-S5U */
|
||||
rv = smf_epc_pfcp_send_session_modification_request(sess, xact, gtpbuf,
|
||||
flags|OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
OGS_GTP2_CAUSE_UNDEFINED_VALUE);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
||||
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
|
||||
ogs_expect_or_return(rv == OGS_OK);
|
||||
} else {
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
/* Check if Handover from Non-3GPP to 3GPP */
|
||||
ogs_gtp2_indication_t *indication = NULL;
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_gtp2_send_modify_bearer_response(sess, xact, req, false));
|
||||
|
||||
if (req->indication_flags.presence &&
|
||||
req->indication_flags.data && req->indication_flags.len) {
|
||||
|
@ -456,20 +528,11 @@ void smf_s5c_handle_modify_bearer_request(
|
|||
}
|
||||
|
||||
if (indication && indication->handover_indication) {
|
||||
ogs_assert(sess->session.name);
|
||||
wlan_sess = smf_sess_find_by_apn(
|
||||
smf_ue, sess->session.name, OGS_GTP2_RAT_TYPE_WLAN);
|
||||
ogs_expect_or_return(wlan_sess);
|
||||
ogs_expect_or_return(ogs_list_first(&wlan_sess->bearer_list));
|
||||
|
||||
ogs_assert(OGS_OK ==
|
||||
smf_epc_pfcp_send_session_modification_request(
|
||||
wlan_sess, NULL,
|
||||
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
|
||||
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
|
||||
ogs_assert(OGS_OK == smf_epc_pfcp_send_deactivation(sess,
|
||||
OGS_GTP2_CAUSE_ACCESS_CHANGED_FROM_NON_3GPP_TO_3GPP));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void smf_s5c_handle_create_bearer_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||
|
|
|
@ -39,7 +39,7 @@ uint8_t smf_s5c_handle_delete_session_request(
|
|||
ogs_gtp2_delete_session_request_t *req);
|
||||
void smf_s5c_handle_modify_bearer_request(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||
ogs_gtp2_modify_bearer_request_t *req);
|
||||
ogs_pkbuf_t *gtpbuf, ogs_gtp2_modify_bearer_request_t *req);
|
||||
void smf_s5c_handle_create_bearer_response(
|
||||
smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
||||
ogs_gtp2_create_bearer_response_t *req);
|
||||
|
|
|
@ -103,17 +103,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
}
|
||||
e->gtp2_message = >p2_message;
|
||||
|
||||
if (gtp2_message.h.teid != 0) {
|
||||
sess = smf_sess_find_by_teid(gtp2_message.h.teid);
|
||||
}
|
||||
|
||||
if (sess) {
|
||||
gnode = sess->gnode;
|
||||
ogs_assert(gnode);
|
||||
} else {
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_receive(gnode, >p2_message.h, >p_xact);
|
||||
if (rv != OGS_OK) {
|
||||
|
@ -122,6 +113,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
}
|
||||
e->gtp_xact = gtp_xact;
|
||||
|
||||
if (gtp2_message.h.teid != 0) {
|
||||
sess = smf_sess_find_by_teid(gtp2_message.h.teid);
|
||||
}
|
||||
|
||||
switch(gtp2_message.h.type) {
|
||||
case OGS_GTP2_ECHO_REQUEST_TYPE:
|
||||
smf_s5c_handle_echo_request(gtp_xact, >p2_message.echo_request);
|
||||
|
@ -157,7 +152,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
break;
|
||||
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
|
||||
smf_s5c_handle_modify_bearer_request(
|
||||
sess, gtp_xact, >p2_message.modify_bearer_request);
|
||||
sess, gtp_xact, recvbuf, >p2_message.modify_bearer_request);
|
||||
break;
|
||||
case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE:
|
||||
smf_s5c_handle_create_bearer_response(
|
||||
|
@ -202,13 +197,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
sess = smf_sess_find_by_teid(gtp1_message.h.teid);
|
||||
}
|
||||
|
||||
if (sess) {
|
||||
gnode = sess->gnode;
|
||||
ogs_assert(gnode);
|
||||
} else {
|
||||
gnode = e->gnode;
|
||||
ogs_assert(gnode);
|
||||
}
|
||||
|
||||
rv = ogs_gtp1_xact_receive(gnode, >p1_message.h, >p_xact);
|
||||
if (rv != OGS_OK) {
|
||||
|
@ -380,6 +370,13 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
|
||||
e->pfcp_message = &pfcp_message;
|
||||
e->pfcp_xact = pfcp_xact;
|
||||
|
||||
e->gtp2_message = NULL;
|
||||
if (pfcp_xact->gtpbuf) {
|
||||
rv = ogs_gtp2_parse_msg(>p2_message, pfcp_xact->gtpbuf);
|
||||
e->gtp2_message = >p2_message;
|
||||
}
|
||||
|
||||
ogs_fsm_dispatch(&pfcp_node->sm, e);
|
||||
if (OGS_FSM_CHECK(&pfcp_node->sm, smf_pfcp_state_exception)) {
|
||||
ogs_error("PFCP state machine exception");
|
||||
|
|
|
@ -179,7 +179,8 @@ static void _gtpv1_tun_recv_common_cb(
|
|||
for (i = 0; i < pdr->num_of_urr; i++)
|
||||
upf_sess_urr_acc_add(sess, pdr->urr[i], recvbuf->len, false);
|
||||
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(pdr, recvbuf, &report));
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(
|
||||
pdr, OGS_GTPU_MSGTYPE_GPDU, recvbuf, &report));
|
||||
|
||||
if (report.type.downlink_data_report) {
|
||||
ogs_assert(pdr->sess);
|
||||
|
@ -539,7 +540,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
ogs_warn("ogs_tun_write() failed");
|
||||
|
||||
} else if (far->dst_if == OGS_PFCP_INTERFACE_ACCESS) {
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(pdr, pkbuf, &report));
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(
|
||||
pdr, gtp_h->type, pkbuf, &report));
|
||||
|
||||
if (report.type.downlink_data_report) {
|
||||
ogs_error("Indirect Data Fowarding Buffered");
|
||||
|
@ -565,7 +567,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(pdr, pkbuf, &report));
|
||||
ogs_assert(true == ogs_pfcp_up_handle_pdr(
|
||||
pdr, gtp_h->type, pkbuf, &report));
|
||||
|
||||
ogs_assert(report.type.downlink_data_report == 0);
|
||||
|
||||
|
@ -755,7 +758,8 @@ static void upf_gtp_handle_multicast(ogs_pkbuf_t *recvbuf)
|
|||
ogs_list_for_each(&sess->pfcp.pdr_list, pdr) {
|
||||
if (pdr->src_if == OGS_PFCP_INTERFACE_CORE) {
|
||||
ogs_assert(true ==
|
||||
ogs_pfcp_up_handle_pdr(pdr, recvbuf, &report));
|
||||
ogs_pfcp_up_handle_pdr(pdr,
|
||||
OGS_GTPU_MSGTYPE_GPDU, recvbuf, &report));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,6 +400,78 @@ void tests1ap_handle_handover_request(
|
|||
test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID;
|
||||
}
|
||||
|
||||
void tests1ap_handle_path_switch_request_ack(
|
||||
test_ue_t *test_ue, ogs_s1ap_message_t *message)
|
||||
{
|
||||
int rv, i;
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
|
||||
test_sess_t *sess = NULL;
|
||||
test_bearer_t *bearer = NULL;
|
||||
|
||||
S1AP_S1AP_PDU_t pdu;
|
||||
S1AP_SuccessfulOutcome_t *successfulOutcome = NULL;
|
||||
S1AP_PathSwitchRequestAcknowledge_t *PathSwitchRequestAcknowledge = NULL;
|
||||
|
||||
S1AP_PathSwitchRequestAcknowledgeIEs_t *ie = NULL;
|
||||
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
|
||||
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
|
||||
S1AP_E_RABToBeSwitchedULList_t *E_RABToBeSwitchedULList = NULL;
|
||||
|
||||
ogs_assert(test_ue);
|
||||
ogs_assert(message);
|
||||
|
||||
successfulOutcome = message->choice.successfulOutcome;
|
||||
ogs_assert(successfulOutcome);
|
||||
PathSwitchRequestAcknowledge = &successfulOutcome->value.choice.PathSwitchRequestAcknowledge;
|
||||
ogs_assert(PathSwitchRequestAcknowledge);
|
||||
|
||||
for (i = 0; i < PathSwitchRequestAcknowledge->protocolIEs.list.count; i++) {
|
||||
ie = PathSwitchRequestAcknowledge->protocolIEs.list.array[i];
|
||||
switch (ie->id) {
|
||||
case S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID:
|
||||
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
|
||||
break;
|
||||
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
|
||||
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
|
||||
break;
|
||||
case S1AP_ProtocolIE_ID_id_E_RABToBeSwitchedULList:
|
||||
E_RABToBeSwitchedULList =
|
||||
&ie->value.choice.E_RABToBeSwitchedULList;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (MME_UE_S1AP_ID)
|
||||
test_ue->mme_ue_s1ap_id = *MME_UE_S1AP_ID;
|
||||
if (ENB_UE_S1AP_ID)
|
||||
test_ue->enb_ue_s1ap_id = *ENB_UE_S1AP_ID;
|
||||
|
||||
if (E_RABToBeSwitchedULList) {
|
||||
for (i = 0; i < E_RABToBeSwitchedULList->list.count; i++) {
|
||||
S1AP_E_RABToBeSwitchedULItemIEs_t *ie2 = NULL;
|
||||
S1AP_E_RABToBeSwitchedULItem_t *e_rab = NULL;
|
||||
|
||||
ie2 = (S1AP_E_RABToBeSwitchedULItemIEs_t *)
|
||||
E_RABToBeSwitchedULList->list.array[i];
|
||||
ogs_assert(ie2);
|
||||
e_rab = &ie2->value.choice.E_RABToBeSwitchedULItem;
|
||||
|
||||
bearer = test_bearer_find_by_ue_ebi(test_ue, e_rab->e_RAB_ID);
|
||||
ogs_assert(bearer);
|
||||
|
||||
memcpy(&bearer->sgw_s1u_teid, e_rab->gTP_TEID.buf,
|
||||
sizeof(bearer->sgw_s1u_teid));
|
||||
bearer->sgw_s1u_teid = be32toh(bearer->sgw_s1u_teid);
|
||||
rv = ogs_asn_BIT_STRING_to_ip(
|
||||
&e_rab->transportLayerAddress, &bearer->sgw_s1u_ip);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tests1ap_handle_handover_command(
|
||||
test_ue_t *test_ue, ogs_s1ap_message_t *message)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,8 @@ void tests1ap_handle_e_rab_modify_request(
|
|||
void tests1ap_handle_e_rab_release_command(
|
||||
test_ue_t *test_ue, ogs_s1ap_message_t *message);
|
||||
|
||||
void tests1ap_handle_path_switch_request_ack(
|
||||
test_ue_t *test_ue, ogs_s1ap_message_t *message);
|
||||
void tests1ap_handle_handover_request(
|
||||
test_ue_t *test_ue, ogs_s1ap_message_t *message);
|
||||
void tests1ap_handle_handover_command(
|
||||
|
|
|
@ -97,6 +97,7 @@ void tests1ap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
|
|||
tests1ap_handle_s1_setup_response(pdu);
|
||||
break;
|
||||
case S1AP_ProcedureCode_id_PathSwitchRequest:
|
||||
tests1ap_handle_path_switch_request_ack(test_ue, pdu);
|
||||
break;
|
||||
case S1AP_ProcedureCode_id_HandoverPreparation:
|
||||
tests1ap_handle_handover_command(test_ue, pdu);
|
||||
|
|
|
@ -27,20 +27,21 @@ ogs_pkbuf_t *test_s2b_build_create_session_request(
|
|||
test_ue_t *test_ue = NULL;
|
||||
test_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;
|
||||
|
||||
uint8_t msisdn_buf[OGS_MAX_MSISDN_LEN];
|
||||
int msisdn_len;
|
||||
|
||||
ogs_gtp2_uli_t uli;
|
||||
char uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
ogs_gtp2_f_teid_t test_s2b_c_teid, test_s2b_u_teid;
|
||||
int len;
|
||||
ogs_gtp2_f_teid_t test_s2b_c_teid, test_s2b_u_teid[OGS_BEARER_PER_UE];
|
||||
int len, test_s2b_u_len;
|
||||
ogs_paa_t paa;
|
||||
|
||||
ogs_gtp2_ambr_t ambr;
|
||||
ogs_gtp2_bearer_qos_t bearer_qos;
|
||||
char bearer_qos_buf[GTP2_BEARER_QOS_LEN];
|
||||
char bearer_qos_buf[OGS_BEARER_PER_UE][GTP2_BEARER_QOS_LEN];
|
||||
char apn[OGS_MAX_APN_LEN+1];
|
||||
|
||||
ogs_gtp2_indication_t indication;
|
||||
|
@ -128,31 +129,40 @@ ogs_pkbuf_t *test_s2b_build_create_session_request(
|
|||
req->aggregate_maximum_bit_rate.data = &ambr;
|
||||
req->aggregate_maximum_bit_rate.len = sizeof(ambr);
|
||||
|
||||
req->bearer_contexts_to_be_created.presence = 1;
|
||||
req->bearer_contexts_to_be_created.eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts_to_be_created.eps_bearer_id.u8 = bearer->ebi;
|
||||
int i = 0;
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_assert(i < OGS_BEARER_PER_UE);
|
||||
|
||||
memset(&test_s2b_u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
test_s2b_u_teid.teid = htobe32(bearer->enb_s1u_teid);
|
||||
test_s2b_u_teid.interface_type = OGS_GTP2_F_TEID_S2B_U_EPDG_GTP_U;
|
||||
req->bearer_contexts_to_be_created[i].presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].eps_bearer_id.presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].eps_bearer_id.u8 = bearer->ebi;
|
||||
|
||||
memset(&test_s2b_u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
||||
test_s2b_u_teid[i].teid = htobe32(bearer->enb_s1u_teid);
|
||||
test_s2b_u_teid[i].interface_type = OGS_GTP2_F_TEID_S2B_U_EPDG_GTP_U;
|
||||
ogs_assert(sess->gnode->sock);
|
||||
rv = ogs_gtp2_sockaddr_to_f_teid(
|
||||
&sess->gnode->sock->local_addr, NULL, &test_s2b_u_teid, &len);
|
||||
&sess->gnode->sock->local_addr, NULL,
|
||||
&test_s2b_u_teid[i], &test_s2b_u_len);
|
||||
|
||||
req->bearer_contexts_to_be_created.s2b_u_epdg_f_teid_5.presence = 1;
|
||||
req->bearer_contexts_to_be_created.s2b_u_epdg_f_teid_5.data =
|
||||
&test_s2b_u_teid;
|
||||
req->bearer_contexts_to_be_created.s2b_u_epdg_f_teid_5.len = len;
|
||||
req->bearer_contexts_to_be_created[i].s2b_u_epdg_f_teid_5.presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].s2b_u_epdg_f_teid_5.data =
|
||||
&test_s2b_u_teid[i];
|
||||
req->bearer_contexts_to_be_created[i].s2b_u_epdg_f_teid_5.len =
|
||||
test_s2b_u_len;
|
||||
|
||||
memset(&bearer_qos, 0, sizeof(bearer_qos));
|
||||
bearer_qos.qci = 8;
|
||||
bearer_qos.priority_level = 1;
|
||||
bearer_qos.pre_emption_capability = 0;
|
||||
bearer_qos.pre_emption_vulnerability = 0;
|
||||
req->bearer_contexts_to_be_created.bearer_level_qos.presence = 1;
|
||||
req->bearer_contexts_to_be_created[i].bearer_level_qos.presence = 1;
|
||||
ogs_gtp2_build_bearer_qos(
|
||||
&req->bearer_contexts_to_be_created.bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf, GTP2_BEARER_QOS_LEN);
|
||||
&req->bearer_contexts_to_be_created[i].bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf[i], GTP2_BEARER_QOS_LEN);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
req->recovery.presence = 1;
|
||||
req->recovery.u8 = 66;
|
||||
|
|
|
@ -24,7 +24,7 @@ void test_s2b_handle_create_session_response(
|
|||
ogs_gtp_xact_t *xact, test_sess_t *sess,
|
||||
ogs_gtp2_create_session_response_t *rsp)
|
||||
{
|
||||
int rv;
|
||||
int rv, i;
|
||||
uint8_t cause_value;
|
||||
|
||||
test_bearer_t *bearer = NULL;
|
||||
|
@ -58,18 +58,6 @@ void test_s2b_handle_create_session_response(
|
|||
ogs_error("No S5/S8 TEID");
|
||||
return;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.presence == 0) {
|
||||
ogs_error("No Bearer Context");
|
||||
return;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EBI");
|
||||
return;
|
||||
}
|
||||
if (rsp->bearer_contexts_created.s12_rnc_f_teid.presence == 0) {
|
||||
ogs_error("No S1U TEID");
|
||||
return;
|
||||
}
|
||||
if (rsp->pdn_address_allocation.presence == 0) {
|
||||
ogs_error("No PDN Address Allocation");
|
||||
return;
|
||||
|
@ -78,22 +66,37 @@ void test_s2b_handle_create_session_response(
|
|||
ogs_expect(
|
||||
rsp->pdn_address_allocation.data && rsp->pdn_address_allocation.len);
|
||||
|
||||
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
||||
if (rsp->bearer_contexts_created[i].presence == 0) {
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].eps_bearer_id.presence == 0) {
|
||||
ogs_error("No EBI");
|
||||
break;
|
||||
}
|
||||
if (rsp->bearer_contexts_created[i].s12_rnc_f_teid.presence == 0) {
|
||||
ogs_error("No S1U TEID");
|
||||
break;
|
||||
}
|
||||
|
||||
bearer = test_bearer_find_by_sess_ebi(
|
||||
sess, rsp->bearer_contexts_created.eps_bearer_id.u8);
|
||||
sess, rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
||||
ogs_assert(bearer);
|
||||
|
||||
smf_s2b_c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.data;
|
||||
ogs_assert(smf_s2b_c_teid);
|
||||
|
||||
sess->smf_s2b_c_teid = be32toh(smf_s2b_c_teid->teid);
|
||||
|
||||
smf_s2b_u_teid = rsp->bearer_contexts_created.s12_rnc_f_teid.data;
|
||||
smf_s2b_u_teid = rsp->bearer_contexts_created[i].s12_rnc_f_teid.data;
|
||||
ogs_assert(smf_s2b_u_teid);
|
||||
|
||||
bearer->sgw_s1u_teid = be32toh(smf_s2b_u_teid->teid);
|
||||
ogs_assert(OGS_OK ==
|
||||
ogs_gtp2_f_teid_to_ip(smf_s2b_u_teid, &bearer->sgw_s1u_ip));
|
||||
|
||||
}
|
||||
|
||||
smf_s2b_c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.data;
|
||||
ogs_assert(smf_s2b_c_teid);
|
||||
|
||||
sess->smf_s2b_c_teid = be32toh(smf_s2b_c_teid->teid);
|
||||
|
||||
memcpy(&paa,
|
||||
rsp->pdn_address_allocation.data, rsp->pdn_address_allocation.len);
|
||||
|
||||
|
|
|
@ -153,18 +153,18 @@ static void gtp_message_test1(abts_case *tc, void *data)
|
|||
req.protocol_configuration_options.len =
|
||||
ogs_pco_build(pcobuf, OGS_MAX_PCO_LEN, &pco);
|
||||
|
||||
req.bearer_contexts_to_be_created.presence = 1;
|
||||
req.bearer_contexts_to_be_created.eps_bearer_id.presence = 1;
|
||||
req.bearer_contexts_to_be_created.eps_bearer_id.u8 = 5;
|
||||
req.bearer_contexts_to_be_created[0].presence = 1;
|
||||
req.bearer_contexts_to_be_created[0].eps_bearer_id.presence = 1;
|
||||
req.bearer_contexts_to_be_created[0].eps_bearer_id.u8 = 5;
|
||||
|
||||
memset(&bearer_qos, 0, sizeof(bearer_qos));
|
||||
bearer_qos.pre_emption_vulnerability = 1;
|
||||
bearer_qos.priority_level = 1;
|
||||
bearer_qos.pre_emption_capability = 1;
|
||||
bearer_qos.qci = 5;
|
||||
req.bearer_contexts_to_be_created.bearer_level_qos.presence = 1;
|
||||
req.bearer_contexts_to_be_created[0].bearer_level_qos.presence = 1;
|
||||
size = ogs_gtp2_build_bearer_qos(
|
||||
&req.bearer_contexts_to_be_created.bearer_level_qos,
|
||||
&req.bearer_contexts_to_be_created[0].bearer_level_qos,
|
||||
&bearer_qos, bearer_qos_buf, GTP2_BEARER_QOS_LEN);
|
||||
|
||||
memset(&ue_timezone, 0, sizeof(ue_timezone));
|
||||
|
@ -259,38 +259,43 @@ static void gtp_message_test1(abts_case *tc, void *data)
|
|||
OGS_PCO_ID_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING,
|
||||
pco.ids[2].id);
|
||||
ABTS_INT_EQUAL(tc, 0, pco.ids[2].len);
|
||||
ABTS_INT_EQUAL(tc, 1, req.bearer_contexts_to_be_created.presence);
|
||||
ABTS_INT_EQUAL(tc, 1, req.bearer_contexts_to_be_created[0].presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.bearer_contexts_to_be_created[1].presence);
|
||||
ABTS_INT_EQUAL(tc, 1, req.
|
||||
bearer_contexts_to_be_created.eps_bearer_id.presence);
|
||||
bearer_contexts_to_be_created[0].eps_bearer_id.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created[1].eps_bearer_id.presence);
|
||||
ABTS_INT_EQUAL(tc, 0x05,
|
||||
req.bearer_contexts_to_be_created.eps_bearer_id.u8);
|
||||
req.bearer_contexts_to_be_created[0].eps_bearer_id.u8);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.tft.presence);
|
||||
bearer_contexts_to_be_created[0].tft.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.s1_u_enodeb_f_teid.presence);
|
||||
bearer_contexts_to_be_created[0].s1_u_enodeb_f_teid.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.s2b_u_epdg_f_teid_5.presence);
|
||||
bearer_contexts_to_be_created[0].s2b_u_epdg_f_teid_5.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.s2a_u_twan_f_teid_6.presence);
|
||||
bearer_contexts_to_be_created[0].s2a_u_twan_f_teid_6.presence);
|
||||
ABTS_INT_EQUAL(tc, 1, req.
|
||||
bearer_contexts_to_be_created.bearer_level_qos.presence);
|
||||
bearer_contexts_to_be_created[0].bearer_level_qos.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created[1].bearer_level_qos.presence);
|
||||
ABTS_INT_EQUAL(tc, 22,
|
||||
req.bearer_contexts_to_be_created.bearer_level_qos.len);
|
||||
req.bearer_contexts_to_be_created[0].bearer_level_qos.len);
|
||||
size = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
||||
&req.bearer_contexts_to_be_created.bearer_level_qos);
|
||||
&req.bearer_contexts_to_be_created[0].bearer_level_qos);
|
||||
ABTS_INT_EQUAL(tc, 22, size);
|
||||
ABTS_INT_EQUAL(tc, 1, bearer_qos.pre_emption_vulnerability);
|
||||
ABTS_INT_EQUAL(tc, 1, bearer_qos.priority_level);
|
||||
ABTS_INT_EQUAL(tc, 1, bearer_qos.pre_emption_capability);
|
||||
ABTS_INT_EQUAL(tc, 5, bearer_qos.qci);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.s11_u_mme_f_teid.presence);
|
||||
bearer_contexts_to_be_created[0].s11_u_mme_f_teid.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.cause.presence);
|
||||
bearer_contexts_to_be_created[0].cause.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.transaction_identifier.presence);
|
||||
bearer_contexts_to_be_created[0].transaction_identifier.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.
|
||||
bearer_contexts_to_be_created.packet_flow_id.presence);
|
||||
bearer_contexts_to_be_created[0].packet_flow_id.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.bearer_contexts_to_be_removed.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.recovery.presence);
|
||||
ABTS_INT_EQUAL(tc, 0, req.mme_fq_csid.presence);
|
||||
|
|
Loading…
Reference in New Issue