301 lines
10 KiB
C
301 lines
10 KiB
C
/*
|
|
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
|
*
|
|
* This file is part of Open5GS.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "test-common.h"
|
|
|
|
ogs_pkbuf_t *test_s2b_build_create_session_request(
|
|
uint8_t type, test_sess_t *sess, bool handover_ind)
|
|
{
|
|
int rv;
|
|
ogs_session_t *session = NULL;
|
|
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;
|
|
|
|
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[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[OGS_BEARER_PER_UE][GTP2_BEARER_QOS_LEN];
|
|
char apn[OGS_MAX_APN_LEN+1];
|
|
|
|
ogs_gtp2_indication_t indication;
|
|
|
|
ogs_assert(sess);
|
|
test_ue = sess->test_ue;
|
|
ogs_assert(test_ue);
|
|
|
|
ogs_assert(0 == ogs_list_count(&sess->bearer_list));
|
|
|
|
bearer = test_bearer_add(sess, 5);
|
|
ogs_assert(bearer);
|
|
|
|
ogs_debug("Create Session Request");
|
|
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
|
|
|
if (handover_ind == true) {
|
|
memset(&indication, 0, sizeof(ogs_gtp2_indication_t));
|
|
indication.handover_indication = 1;
|
|
req->indication_flags.presence = 1;
|
|
req->indication_flags.data = &indication;
|
|
req->indication_flags.len = sizeof(ogs_gtp2_indication_t);
|
|
}
|
|
|
|
ogs_assert(test_ue->imsi_len);
|
|
req->imsi.presence = 1;
|
|
req->imsi.data = test_ue->imsi_buf;
|
|
req->imsi.len = test_ue->imsi_len;
|
|
|
|
ogs_bcd_to_buffer(TEST_MSISDN, msisdn_buf, &msisdn_len);
|
|
|
|
req->msisdn.presence = 1;
|
|
req->msisdn.data = msisdn_buf;
|
|
req->msisdn.len = msisdn_len;
|
|
|
|
memset(&uli, 0, sizeof(ogs_gtp2_uli_t));
|
|
uli.flags.e_cgi = 1;
|
|
uli.flags.tai = 1;
|
|
ogs_nas_from_plmn_id(&uli.tai.nas_plmn_id, &test_ue->e_tai.plmn_id);
|
|
uli.tai.tac = test_ue->e_tai.tac;
|
|
ogs_nas_from_plmn_id(&uli.e_cgi.nas_plmn_id, &test_ue->e_cgi.plmn_id);
|
|
uli.e_cgi.cell_id = test_ue->e_cgi.cell_id;
|
|
req->user_location_information.presence = 1;
|
|
ogs_gtp2_build_uli(&req->user_location_information, &uli,
|
|
uli_buf, OGS_GTP2_MAX_ULI_LEN);
|
|
|
|
req->serving_network.presence = 1;
|
|
req->serving_network.data = &uli.tai.nas_plmn_id;
|
|
req->serving_network.len = sizeof(uli.tai.nas_plmn_id);
|
|
|
|
req->rat_type.presence = 1;
|
|
req->rat_type.u8 = OGS_GTP2_RAT_TYPE_WLAN;
|
|
|
|
memset(&test_s2b_c_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
|
test_s2b_c_teid.interface_type = OGS_GTP2_F_TEID_S2B_EPDG_GTP_C;
|
|
test_s2b_c_teid.teid = htobe32(sess->epdg_s2b_c_teid);
|
|
ogs_assert(sess->gnode->sock);
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
|
&sess->gnode->sock->local_addr, NULL, &test_s2b_c_teid, &len);
|
|
ogs_assert(rv == OGS_OK);
|
|
req->sender_f_teid_for_control_plane.presence = 1;
|
|
req->sender_f_teid_for_control_plane.data = &test_s2b_c_teid;
|
|
req->sender_f_teid_for_control_plane.len = len;
|
|
|
|
req->access_point_name.presence = 1;
|
|
req->access_point_name.len = ogs_fqdn_build(
|
|
apn, sess->apn, strlen(sess->apn));
|
|
req->access_point_name.data = apn;
|
|
|
|
req->selection_mode.presence = 1;
|
|
req->selection_mode.u8 =
|
|
OGS_GTP2_SELECTION_MODE_MS_OR_NETWORK_PROVIDED_APN;
|
|
|
|
memset(&paa, 0, sizeof(paa));
|
|
paa.session_type = OGS_PDU_SESSION_TYPE_IPV4V6;
|
|
|
|
req->pdn_address_allocation.presence = 1;
|
|
req->pdn_address_allocation.data = &paa;
|
|
req->pdn_address_allocation.len = OGS_PAA_IPV4V6_LEN;
|
|
|
|
memset(&ambr, 0, sizeof(ogs_gtp2_ambr_t));
|
|
ambr.uplink = htobe32(50000);
|
|
ambr.downlink = htobe32(150000);
|
|
req->aggregate_maximum_bit_rate.presence = 1;
|
|
req->aggregate_maximum_bit_rate.data = &ambr;
|
|
req->aggregate_maximum_bit_rate.len = sizeof(ambr);
|
|
|
|
int i = 0;
|
|
ogs_list_for_each(&sess->bearer_list, bearer) {
|
|
ogs_assert(i < OGS_BEARER_PER_UE);
|
|
|
|
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[i], &test_s2b_u_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[i].bearer_level_qos.presence = 1;
|
|
ogs_gtp2_build_bearer_qos(
|
|
&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;
|
|
|
|
req->additional_protocol_configuration_options.presence = 1;
|
|
req->additional_protocol_configuration_options.data =
|
|
(uint8_t *)"\x80\x00\x0d\x00";
|
|
req->additional_protocol_configuration_options.len = 4;
|
|
|
|
gtp_message.h.type = type;
|
|
return ogs_gtp2_build_msg(>p_message);
|
|
}
|
|
|
|
ogs_pkbuf_t *test_s2b_build_delete_session_request(
|
|
uint8_t type, test_sess_t *sess)
|
|
{
|
|
int rv;
|
|
test_bearer_t *bearer = NULL;
|
|
|
|
ogs_gtp2_message_t gtp_message;
|
|
ogs_gtp2_delete_session_request_t *req = >p_message.delete_session_request;
|
|
|
|
ogs_assert(sess);
|
|
bearer = ogs_list_first(&sess->bearer_list);
|
|
ogs_assert(bearer);
|
|
|
|
ogs_debug("Delete Session Request");
|
|
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
|
|
|
req->linked_eps_bearer_id.presence = 1;
|
|
req->linked_eps_bearer_id.u8 = bearer->ebi;
|
|
|
|
gtp_message.h.type = type;
|
|
return ogs_gtp2_build_msg(>p_message);
|
|
}
|
|
|
|
ogs_pkbuf_t *test_s2b_build_create_bearer_response(
|
|
uint8_t type, test_bearer_t *bearer)
|
|
{
|
|
int rv;
|
|
ogs_session_t *session = NULL;
|
|
ogs_gtp2_message_t gtp_message;
|
|
ogs_gtp2_create_bearer_response_t *rsp = NULL;
|
|
|
|
test_sess_t *sess = NULL;
|
|
|
|
ogs_gtp2_cause_t cause;
|
|
ogs_gtp2_f_teid_t epdg_s2b_u_teid, smf_s2b_u_teid;
|
|
int len;
|
|
|
|
ogs_assert(bearer);
|
|
sess = bearer->sess;
|
|
ogs_assert(sess);
|
|
|
|
ogs_debug("Create Bearer Response");
|
|
rsp = >p_message.create_bearer_response;
|
|
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
|
|
|
memset(&cause, 0, sizeof(cause));
|
|
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
rsp->cause.presence = 1;
|
|
rsp->cause.data = &cause;
|
|
rsp->cause.len = sizeof(cause);
|
|
|
|
/* Bearer Context : EBI */
|
|
rsp->bearer_contexts.presence = 1;
|
|
rsp->bearer_contexts.eps_bearer_id.presence = 1;
|
|
rsp->bearer_contexts.eps_bearer_id.u8 = bearer->ebi;
|
|
|
|
/* Data Plane(DL) : ePDG-S2B-U */
|
|
memset(&epdg_s2b_u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
|
epdg_s2b_u_teid.interface_type = OGS_GTP2_F_TEID_S2B_U_EPDG_GTP_U;
|
|
epdg_s2b_u_teid.teid = htobe32(bearer->enb_s1u_teid);
|
|
ogs_assert(sess->gnode->sock);
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
|
&sess->gnode->sock->local_addr, NULL, &epdg_s2b_u_teid, &len);
|
|
if (rv != OGS_OK) {
|
|
ogs_error("ogs_gtp2_sockaddr_to_f_teid() failed");
|
|
return NULL;
|
|
}
|
|
rsp->bearer_contexts.s2b_u_epdg_f_teid_8.presence = 1;
|
|
rsp->bearer_contexts.s2b_u_epdg_f_teid_8.data = &epdg_s2b_u_teid;
|
|
rsp->bearer_contexts.s2b_u_epdg_f_teid_8.len = len;
|
|
|
|
/* Data Plane(UL) : SMF-S2B-U */
|
|
memset(&smf_s2b_u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
|
smf_s2b_u_teid.interface_type = OGS_GTP2_F_TEID_S2B_U_PGW_GTP_U;
|
|
smf_s2b_u_teid.teid = htobe32(bearer->sgw_s1u_teid);
|
|
rv = ogs_gtp2_ip_to_f_teid(&bearer->sgw_s1u_ip, &smf_s2b_u_teid, &len);
|
|
if (rv != OGS_OK) {
|
|
ogs_error("ogs_gtp2_ip_to_f_teid() failed");
|
|
return NULL;
|
|
}
|
|
rsp->bearer_contexts.s2b_u_pgw_f_teid.presence = 1;
|
|
rsp->bearer_contexts.s2b_u_pgw_f_teid.data = &smf_s2b_u_teid;
|
|
rsp->bearer_contexts.s2b_u_pgw_f_teid.len = OGS_GTP2_F_TEID_IPV4_LEN;
|
|
|
|
/* Bearer Context : Cause */
|
|
rsp->bearer_contexts.cause.presence = 1;
|
|
rsp->bearer_contexts.cause.len = sizeof(cause);
|
|
rsp->bearer_contexts.cause.data = &cause;
|
|
|
|
gtp_message.h.type = type;
|
|
return ogs_gtp2_build_msg(>p_message);
|
|
}
|
|
|
|
ogs_pkbuf_t *test_s2b_build_delete_bearer_response(
|
|
uint8_t type, test_bearer_t *bearer)
|
|
{
|
|
int rv;
|
|
ogs_session_t *session = NULL;
|
|
ogs_gtp2_message_t gtp_message;
|
|
ogs_gtp2_delete_bearer_response_t *rsp = NULL;
|
|
|
|
ogs_gtp2_cause_t cause;
|
|
|
|
ogs_assert(bearer);
|
|
|
|
ogs_debug("Delete Bearer Response");
|
|
rsp = >p_message.delete_bearer_response;
|
|
memset(>p_message, 0, sizeof(ogs_gtp2_message_t));
|
|
|
|
memset(&cause, 0, sizeof(cause));
|
|
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
rsp->cause.presence = 1;
|
|
rsp->cause.data = &cause;
|
|
rsp->cause.len = sizeof(cause);
|
|
|
|
rsp->linked_eps_bearer_id.presence = 1;
|
|
rsp->linked_eps_bearer_id.u8 = bearer->ebi;
|
|
|
|
gtp_message.h.type = type;
|
|
return ogs_gtp2_build_msg(>p_message);
|
|
}
|