[TEST] Add S13 end-to-end suite

tests/s13 attaches a UE through the MME against open5gs-eird over S13
and checks what follows Security Mode Complete: ESM Information Request
when the device is admitted, Attach Reject #6 when it is not. Seven
cases cover the three statuses, an unknown device, and the per-subscriber
overrides of the eir collection. The EPC test harness starts the EIR
when an eir section is present, and the test UE now records the Attach
Reject cause.
This commit is contained in:
Alexy 2026-09-21 14:11:32 +02:00
parent 6900e5fb84
commit 54486b2779
10 changed files with 769 additions and 0 deletions

View file

@ -33,6 +33,7 @@ conf_data.set('build_subprojects_freeDiameter_extensions_dir',
example_conf = '''
sample.yaml
eir.yaml
s13.yaml
attach.yaml
dns.yaml
310014.yaml

277
configs/s13.yaml.in Normal file
View file

@ -0,0 +1,277 @@
# Dedicated configuration for tests/s13: EPS attach with the ME Identity
# Check over S13 served by open5gs-eird. The 5GC network functions are not
# started, except the NRF that the EIR registers its SBI service with.
db_uri: mongodb://localhost/open5gs
logger:
test:
serving:
- plmn_id:
mcc: 999
mnc: 70
global:
parameter:
no_scp: true
no_sepp: true
no_amf: true
no_ausf: true
no_udm: true
no_pcf: true
no_nssf: true
no_bsf: true
no_udr: true
mme:
freeDiameter:
identity: mme.localdomain
realm: localdomain
listen_on: 127.0.0.2
no_fwd: true
load_extension:
- module: @build_subprojects_freeDiameter_extensions_dir@/dbg_msg_dumps.fdx
conf: 0x8888
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_rfc5777.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_mip6i.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nasreq.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nas_mipv6.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca_3gpp/dict_dcca_3gpp.fdx
connect:
- identity: hss.localdomain
address: 127.0.0.8
- identity: eir.localdomain
address: 127.0.0.21
eir:
enabled: true
realm: localdomain
host: eir.localdomain
timeout: 3
max_age: 1 # every test case shares one IMEISV: let verdicts expire
unknown_action: allow
failure_action: allow
missing_pei_action: allow
s1ap:
server:
- address: 127.0.0.2
gtpc:
server:
- address: 127.0.0.2
client:
sgwc:
- address: 127.0.0.3
smf:
- address: 127.0.0.4
metrics:
server:
- address: 127.0.0.2
port: 9090
gummei:
- plmn_id:
mcc: 999
mnc: 70
mme_gid: 2
mme_code: 1
tai:
- plmn_id:
mcc: 999
mnc: 70
tac: 1
security:
integrity_order : [ EIA2, EIA1, EIA0 ]
ciphering_order : [ EEA0, EEA1, EEA2 ]
network_name:
full: Open5GS
time:
t3412:
value: 540
sgwc:
gtpc:
server:
- address: 127.0.0.3
pfcp:
server:
- address: 127.0.0.3
client:
sgwu:
- address: 127.0.0.6
smf:
pfcp:
server:
- address: 127.0.0.4
client:
upf:
- address: 127.0.0.7
gtpc:
server:
- address: 127.0.0.4
gtpu:
server:
- address: 127.0.0.4
metrics:
server:
- address: 127.0.0.4
port: 9090
session:
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
dns:
- 8.8.8.8
- 8.8.4.4
- 2001:4860:4860::8888
- 2001:4860:4860::8844
mtu: 1400
freeDiameter:
identity: smf.localdomain
realm: localdomain
listen_on: 127.0.0.4
no_fwd: true
load_extension:
- module: @build_subprojects_freeDiameter_extensions_dir@/dbg_msg_dumps.fdx
conf: 0x8888
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_rfc5777.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_mip6i.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nasreq.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nas_mipv6.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca_3gpp/dict_dcca_3gpp.fdx
connect:
- identity: pcrf.localdomain
address: 127.0.0.9
amf:
sbi:
server:
- address: 127.0.0.5
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
ngap:
server:
- address: 127.0.0.5
guami:
- plmn_id:
mcc: 999
mnc: 70
amf_id:
region: 2
set: 1
tai:
- plmn_id:
mcc: 999
mnc: 70
tac: 1
plmn_support:
- plmn_id:
mcc: 999
mnc: 70
s_nssai:
- sst: 1
security:
integrity_order : [ NIA2, NIA1, NIA0 ]
ciphering_order : [ NEA0, NEA1, NEA2 ]
network_name:
full: Open5GS
amf_name: open5gs-amf0
sgwu:
pfcp:
server:
- address: 127.0.0.6
gtpu:
server:
- address: 127.0.0.6
upf:
pfcp:
server:
- address: 127.0.0.7
gtpu:
server:
- address: 127.0.0.7
session:
- subnet: 10.45.0.0/16
gateway: 10.45.0.1
- subnet: 2001:db8:cafe::/48
gateway: 2001:db8:cafe::1
metrics:
server:
- address: 127.0.0.7
port: 9090
hss:
freeDiameter:
identity: hss.localdomain
realm: localdomain
listen_on: 127.0.0.8
no_fwd: true
load_extension:
- module: @build_subprojects_freeDiameter_extensions_dir@/dbg_msg_dumps.fdx
conf: 0x8888
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_rfc5777.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_mip6i.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nasreq.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nas_mipv6.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca_3gpp/dict_dcca_3gpp.fdx
connect:
- identity: mme.localdomain
address: 127.0.0.2
pcrf:
freeDiameter:
identity: pcrf.localdomain
realm: localdomain
listen_on: 127.0.0.9
no_fwd: true
load_extension:
- module: @build_subprojects_freeDiameter_extensions_dir@/dbg_msg_dumps.fdx
conf: 0x8888
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_rfc5777.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_mip6i.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nasreq.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nas_mipv6.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca_3gpp/dict_dcca_3gpp.fdx
connect:
- identity: smf.localdomain
address: 127.0.0.4
nrf:
sbi:
server:
- address: 127.0.0.10
port: 7777
eir:
sbi:
server:
- address: 127.0.0.21
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
freeDiameter:
identity: eir.localdomain
realm: localdomain
listen_on: 127.0.0.21
no_fwd: true
load_extension:
- module: @build_subprojects_freeDiameter_extensions_dir@/dbg_msg_dumps.fdx
conf: 0x8888
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_rfc5777.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_mip6i.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nasreq.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_nas_mipv6.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca.fdx
- module: @build_subprojects_freeDiameter_extensions_dir@/dict_dcca_3gpp/dict_dcca_3gpp.fdx
connect:
- identity: mme.localdomain
address: 127.0.0.2

View file

@ -24,6 +24,7 @@ static ogs_thread_t *scp_thread = NULL;
static ogs_thread_t *sepp_thread = NULL;
static ogs_thread_t *pcrf_thread = NULL;
static ogs_thread_t *hss_thread = NULL;
static ogs_thread_t *eir_thread = NULL;
static ogs_thread_t *upf_thread = NULL;
static ogs_thread_t *sgwc_thread = NULL;
static ogs_thread_t *sgwu_thread = NULL;
@ -65,6 +66,9 @@ int app_initialize(const char *const argv[])
sepp_thread = test_child_create("sepp", 0, argv_out);
if (ogs_global_conf()->parameter.no_hss == 0)
hss_thread = test_child_create("hss", 0, argv_out);
if (ogs_global_conf()->parameter.no_eir == 0 &&
ogs_global_conf()->parameter.eir_count > 0)
eir_thread = test_child_create("eir", 0, argv_out);
if (ogs_global_conf()->parameter.no_pcrf == 0)
pcrf_thread = test_child_create("pcrf", 0, argv_out);
@ -124,6 +128,7 @@ void app_terminate(void)
if (udm_thread) ogs_thread_destroy(udm_thread);
if (ausf_thread) ogs_thread_destroy(ausf_thread);
if (eir_thread) ogs_thread_destroy(eir_thread);
if (hss_thread) ogs_thread_destroy(hss_thread);
if (pcrf_thread) ogs_thread_destroy(pcrf_thread);

View file

@ -25,6 +25,7 @@ static ogs_thread_t *smf_thread = NULL;
static ogs_thread_t *sgwc_thread = NULL;
static ogs_thread_t *sgwu_thread = NULL;
static ogs_thread_t *hss_thread = NULL;
static ogs_thread_t *eir_thread = NULL;
static ogs_thread_t *mme_thread = NULL;
int app_initialize(const char *const argv[])
@ -49,6 +50,9 @@ int app_initialize(const char *const argv[])
if (ogs_global_conf()->parameter.no_hss == 0)
hss_thread = test_child_create("hss", 0, argv_out);
if (ogs_global_conf()->parameter.no_eir == 0 &&
ogs_global_conf()->parameter.eir_count > 0)
eir_thread = test_child_create("eir", 0, argv_out);
if (ogs_global_conf()->parameter.no_pcrf == 0)
pcrf_thread = test_child_create("pcrf", 0, argv_out);
@ -85,6 +89,7 @@ void app_terminate(void)
if (sgwu_thread) ogs_thread_destroy(sgwu_thread);
if (upf_thread) ogs_thread_destroy(upf_thread);
if (eir_thread) ogs_thread_destroy(eir_thread);
if (hss_thread) ogs_thread_destroy(hss_thread);
if (pcrf_thread) ogs_thread_destroy(pcrf_thread);
}

View file

@ -411,6 +411,7 @@ typedef struct test_ue_s {
/* EPC: Last received message */
S1AP_ProcedureCode_t s1ap_procedure_code;
uint8_t emm_message_type;
ogs_nas_emm_cause_t attach_reject_cause;
uint8_t esm_message_type;
test_sess_t *sess;

View file

@ -160,6 +160,8 @@ void testemm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
testemm_handle_attach_accept(test_ue, &message.emm.attach_accept);
break;
case OGS_NAS_EPS_ATTACH_REJECT:
test_ue->attach_reject_cause =
message.emm.attach_reject.emm_cause;
break;
case OGS_NAS_EPS_SERVICE_REJECT:
break;

View file

@ -25,6 +25,7 @@ subdir('af')
subdir('common')
subdir('app')
subdir('eir')
subdir('s13')
subdir('registration')
subdir('vonr')
subdir('slice')

66
tests/s13/abts-main.c Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright (C) 2026 by LetMeConnect
*
* 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-app.h"
abts_suite *test_s13(abts_suite *suite);
const struct testlist {
abts_suite *(*func)(abts_suite *suite);
} alltests[] = {
{test_s13},
{NULL},
};
static void terminate(void)
{
ogs_msleep(50);
test_child_terminate();
app_terminate();
test_app_final();
ogs_app_terminate();
}
static void initialize(const char *const argv[])
{
int rv;
rv = ogs_app_initialize(NULL, NULL, argv);
ogs_assert(rv == OGS_OK);
test_app_init();
rv = app_initialize(argv);
ogs_assert(rv == OGS_OK);
}
int main(int argc, const char *const argv[])
{
int i;
abts_suite *suite = NULL;
atexit(terminate);
test_app_run(argc, argv, "s13.yaml", initialize);
for (i = 0; alltests[i].func; i++)
suite = alltests[i].func(suite);
return abts_report(suite);
}

14
tests/s13/meson.build Normal file
View file

@ -0,0 +1,14 @@
# Copyright (C) 2026 by LetMeConnect
# SPDX-License-Identifier: AGPL-3.0-or-later
testapp_s13_sources = files('''
abts-main.c
s13-test.c
'''.split())
testapp_s13_exe = executable('s13',
sources : testapp_s13_sources,
c_args : testunit_core_cc_flags,
dependencies : libtestapp_dep)
test('s13', testapp_s13_exe, is_parallel : false, suite: ['s13', 'epc'])

397
tests/s13/s13-test.c Normal file
View file

@ -0,0 +1,397 @@
/*
* Copyright (C) 2026 by LetMeConnect
*
* 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/>.
*/
/*
* ME Identity Check over S13 against the Open5GS EIR (open5gs-eird).
*
* The MME runs with eir.enabled (configs/s13.yaml) and the EIR serves S13
* next to N5g-eir out of the same eir collection. Each case provisions
* records for the test UE IMEISV, runs an EPS attach, and checks what
* follows Security Mode Complete: ESM Information Request when the
* equipment is admitted, Attach Reject #6 Illegal ME when it is not.
*/
#include "test-app.h"
/* test_ue_set_mobile_identity_imsisv(): IMEI 86650704004053 + SVN 01 */
#define S13_TEST_PEI "imeisv-8665070400405301"
#define S13_TEST_OTHER_SUPI "imsi-999700000000099"
typedef struct s13_case_s {
const char *name;
const char *generic_status; /* eir record for the PEI only */
const char *specific_status; /* eir record for the PEI and a SUPI */
bool specific_other_supi; /* ...of another subscriber */
ogs_nas_emm_cause_t reject_cause; /* 0: attach accepted */
} s13_case_t;
static const s13_case_t cases[] = {
{ "whitelisted equipment attaches", "WHITELISTED", NULL, false, 0 },
{ "greylisted equipment attaches", "GREYLISTED", NULL, false, 0 },
{ "blacklisted equipment is rejected", "BLACKLISTED", NULL, false,
OGS_NAS_EMM_CAUSE_ILLEGAL_ME },
{ "unknown equipment attaches with unknown_action allow",
NULL, NULL, false, 0 },
{ "subscriber blacklist overrides generic whitelist",
"WHITELISTED", "BLACKLISTED", false, OGS_NAS_EMM_CAUSE_ILLEGAL_ME },
{ "subscriber whitelist overrides generic blacklist",
"BLACKLISTED", "WHITELISTED", false, 0 },
{ "record of another subscriber does not apply",
"WHITELISTED", "BLACKLISTED", true, 0 },
};
typedef struct fixture_s {
bson_oid_t ids[2];
unsigned int count;
} fixture_t;
static void fixture_insert(abts_case *tc, fixture_t *fixture,
const char *pei, const char *supi, const char *status)
{
bson_error_t error;
bson_t *document = NULL;
unsigned int index = fixture->count++;
ogs_assert(index < OGS_ARRAY_SIZE(fixture->ids));
bson_oid_init(&fixture->ids[index], NULL);
if (supi)
document = BCON_NEW("_id", BCON_OID(&fixture->ids[index]),
"pei", BCON_UTF8(pei), "supi", BCON_UTF8(supi),
"status", BCON_UTF8(status));
else
document = BCON_NEW("_id", BCON_OID(&fixture->ids[index]),
"pei", BCON_UTF8(pei), "status", BCON_UTF8(status));
ogs_assert(document);
if (!mongoc_collection_insert_one(ogs_mongoc()->collection.eir,
document, NULL, NULL, &error))
ABTS_FAIL(tc, error.message);
bson_destroy(document);
}
static void fixture_remove(abts_case *tc, fixture_t *fixture)
{
bson_error_t error;
/* Remove only documents created by this case */
while (fixture->count) {
bson_t *query = BCON_NEW("_id",
BCON_OID(&fixture->ids[--fixture->count]));
if (!mongoc_collection_delete_one(ogs_mongoc()->collection.eir,
query, NULL, NULL, &error))
ABTS_FAIL(tc, error.message);
bson_destroy(query);
}
}
static void s13_case(abts_case *tc, void *data)
{
const s13_case_t *test = data;
int rv;
ogs_socknode_t *s1ap;
ogs_socknode_t *gtpu;
ogs_pkbuf_t *emmbuf;
ogs_pkbuf_t *esmbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t *test_ue = NULL;
test_sess_t *sess = NULL;
test_bearer_t *bearer = NULL;
uint32_t enb_ue_s1ap_id;
bson_t *doc = NULL;
fixture_t fixture;
char *supi = NULL;
ogs_info("[S13] %s", test->name);
memset(&fixture, 0, sizeof(fixture));
/*
* Every case uses the same IMEISV and mme.eir.max_age is 1 second in
* s13.yaml: let the previous verdict expire from the MME cache so that
* the ME-Identity-Check-Request really reaches the EIR.
*/
ogs_msleep(1200);
/* Setup Test UE & Session Context */
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
mobile_identity_suci.routing_indicator1 = 0;
mobile_identity_suci.routing_indicator2 = 0xf;
mobile_identity_suci.routing_indicator3 = 0xf;
mobile_identity_suci.routing_indicator4 = 0xf;
mobile_identity_suci.protection_scheme_id = OGS_PROTECTION_SCHEME_NULL;
mobile_identity_suci.home_network_pki_value = 0;
test_ue = test_ue_add_by_suci(&mobile_identity_suci, "3746000006");
ogs_assert(test_ue);
test_ue->e_cgi.cell_id = 0x1079baf0;
test_ue->nas.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
test_ue->nas.value = OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH;
test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca";
sess = test_sess_add_by_apn(test_ue, "internet", OGS_GTP2_RAT_TYPE_EUTRAN);
ogs_assert(sess);
supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, test_ue->imsi);
ogs_assert(supi);
/* eNB connects to MME */
s1ap = tests1ap_client(AF_INET);
ABTS_PTR_NOTNULL(tc, s1ap);
/* eNB connects to SGW */
gtpu = test_gtpu_server(1, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu);
/* Send S1-Setup Reqeust */
sendbuf = test_s1ap_build_s1_setup_request(
S1AP_ENB_ID_PR_macroENB_ID, 0x54f64);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive S1-Setup Response */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(NULL, recvbuf);
/********** Insert Subscriber in Database */
doc = test_db_new_simple(test_ue);
ABTS_PTR_NOTNULL(tc, doc);
ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc));
/********** Insert equipment records in the eir collection */
if (test->generic_status)
fixture_insert(tc, &fixture, S13_TEST_PEI, NULL, test->generic_status);
if (test->specific_status)
fixture_insert(tc, &fixture, S13_TEST_PEI,
test->specific_other_supi ? S13_TEST_OTHER_SUPI : supi,
test->specific_status);
/* Send Attach Request */
memset(&sess->pdn_connectivity_param,
0, sizeof(sess->pdn_connectivity_param));
sess->pdn_connectivity_param.eit = 1;
sess->pdn_connectivity_param.request_type =
OGS_NAS_EPS_REQUEST_TYPE_INITIAL;
esmbuf = testesm_build_pdn_connectivity_request(
sess, false, OGS_NAS_EPS_PDN_TYPE_IPV4V6);
ABTS_PTR_NOTNULL(tc, esmbuf);
memset(&test_ue->attach_request_param,
0, sizeof(test_ue->attach_request_param));
test_ue->attach_request_param.drx_parameter = 1;
test_ue->attach_request_param.ms_network_capability = 1;
test_ue->attach_request_param.tmsi_status = 1;
test_ue->attach_request_param.mobile_station_classmark_2 = 1;
test_ue->attach_request_param.ue_usage_setting = 1;
emmbuf = testemm_build_attach_request(test_ue, esmbuf, true, false);
ABTS_PTR_NOTNULL(tc, emmbuf);
memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param));
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Authentication Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Authentication response */
emmbuf = testemm_build_authentication_response(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Security mode complete, with the IMEISV the MME checks */
test_ue->mobile_identity_imeisv_presence = true;
emmbuf = testemm_build_security_mode_complete(test_ue);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
if (test->reject_cause) {
/* Receive Attach Reject */
test_ue->emm_message_type = 0;
test_ue->attach_reject_cause = 0;
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc, OGS_NAS_EPS_ATTACH_REJECT,
test_ue->emm_message_type);
ABTS_INT_EQUAL(tc, test->reject_cause, test_ue->attach_reject_cause);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc, S1AP_ProcedureCode_id_UEContextRelease,
test_ue->s1ap_procedure_code);
/* Send UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
goto cleanup;
}
/* Receive ESM Information Request */
test_ue->esm_message_type = 0;
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc, OGS_NAS_EPS_ESM_INFORMATION_REQUEST,
test_ue->esm_message_type);
/* Send ESM Information Response */
sess->esm_information_param.epco = 1;
esmbuf = testesm_build_esm_information_response(sess);
ABTS_PTR_NOTNULL(tc, esmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial Context Setup Request +
* Attach Accept +
* Activate Default Bearer Context Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc, OGS_NAS_EPS_ATTACH_ACCEPT, test_ue->emm_message_type);
/* Send UE Capability Info Indication */
sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Initial Context Setup Response */
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Attach Complete + Activate default EPS bearer cotext accept */
test_ue->nr_cgi.cell_id = 0x1234502;
bearer = test_bearer_find_by_ue_ebi(test_ue, 5);
ogs_assert(bearer);
esmbuf = testesm_build_activate_default_eps_bearer_context_accept(
bearer, false);
ABTS_PTR_NOTNULL(tc, esmbuf);
emmbuf = testemm_build_attach_complete(test_ue, esmbuf);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive EMM information */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send Detach Request */
emmbuf = testemm_build_detach_request(test_ue, 1, true, false);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_initial_ue_message(
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive OLD UE Context Release Command */
enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id;
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send OLD UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id;
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
tests1ap_recv(test_ue, recvbuf);
/* Send UE Context Release Complete */
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
cleanup:
ogs_msleep(300);
/********** Remove equipment records and Subscriber in Database */
fixture_remove(tc, &fixture);
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue));
/* eNB disonncect from MME */
testenb_s1ap_close(s1ap);
/* eNB disonncect from SGW */
test_gtpu_close(gtpu);
ogs_free(supi);
test_ue_remove(test_ue);
}
abts_suite *test_s13(abts_suite *suite)
{
int i;
suite = ADD_SUITE(suite)
for (i = 0; i < OGS_ARRAY_SIZE(cases); i++)
abts_run_test(suite, s13_case, (void *)&cases[i]);
return suite;
}