Merge branch 'main' into home-routed

This commit is contained in:
Sukchan Lee
2025-06-01 16:54:26 +09:00
28 changed files with 1809 additions and 101 deletions

View File

@@ -41,6 +41,7 @@ example_conf = '''
srsenb.yaml srsenb.yaml
non3gpp.yaml non3gpp.yaml
transfer.yaml transfer.yaml
transfer-error-case.yaml
'''.split() '''.split()
foreach file : example_conf foreach file : example_conf

View File

@@ -0,0 +1,266 @@
db_uri: mongodb://localhost/open5gs
logger:
test:
serving:
- plmn_id:
mcc: 999
mnc: 70
global:
parameter:
# no_nrf: true
no_scp: true
no_sepp: true
# no_amf: true
# no_smf: true
# no_upf: true
# no_ausf: true
# no_udm: true
# no_pcf: true
# no_nssf: true
# no_bsf: true
# no_udr: true
no_mme: true
no_sgwc: true
no_sgwu: true
no_pcrf: true
no_hss: true
smf:
sbi:
server:
- address: 127.0.0.4
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
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
metrics:
server:
- address: 127.0.0.5
port: 9090
guami:
- plmn_id:
mcc: 999
mnc: 70
amf_id:
region: 2
set: 1
pointer: 31
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
time:
t3512:
value: 540 # 9 mintues * 60 = 540 seconds
# amf #2
amf:
sbi:
server:
- address: 127.0.0.50
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
ngap:
server:
- address: 127.0.0.50
metrics:
server:
- address: 127.0.0.50
port: 9090
guami:
- plmn_id:
mcc: 999
mnc: 70
amf_id:
region: 2
set: 1
pointer: 30
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-amf1
time:
t3512:
value: 540 # 9 mintues * 60 = 540 seconds
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
nrf:
sbi:
server:
- address: 127.0.0.10
port: 7777
serving:
- plmn_id:
mcc: 999
mnc: 70
ausf:
sbi:
server:
- address: 127.0.0.11
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
udm:
hnet:
- id: 1
scheme: 1
key: @build_configs_dir@/open5gs/hnet/curve25519-1.key
- id: 2
scheme: 2
key: @build_configs_dir@/open5gs/hnet/secp256r1-2.key
sbi:
server:
- address: 127.0.0.12
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
pcf:
sbi:
server:
- address: 127.0.0.13
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
metrics:
server:
- address: 127.0.0.13
port: 9090
nssf:
sbi:
server:
- address: 127.0.0.14
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
nsi:
- uri: http://127.0.0.10:7777
s_nssai:
sst: 1
bsf:
sbi:
server:
- address: 127.0.0.15
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777
udr:
sbi:
server:
- address: 127.0.0.20
port: 7777
client:
nrf:
- uri: http://127.0.0.10:7777

View File

@@ -370,9 +370,17 @@ int ogs_proc_join(ogs_proc_t *const process, int *const out_return_code)
} }
if (process->child != waitpid(process->child, &status, 0)) { if (process->child != waitpid(process->child, &status, 0)) {
process->child = 0;
ogs_error("waitpid failed: %d", status);
return OGS_ERROR; return OGS_ERROR;
} }
process->child = 0;
if (process->nf_name) {
ogs_free(process->nf_name);
process->nf_name = NULL;
}
if (out_return_code) { if (out_return_code) {
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
*out_return_code = WEXITSTATUS(status); *out_return_code = WEXITSTATUS(status);
@@ -416,9 +424,17 @@ int ogs_proc_terminate(ogs_proc_t *const process)
return OGS_ERROR; return OGS_ERROR;
} }
#else #else
if (kill(process->child, SIGTERM) == -1) {
return OGS_ERROR; if (process->child) {
if (kill(process->child, SIGTERM) == -1) {
if (errno == ESRCH) {
/* No such process */
return OGS_OK;
}
return OGS_ERROR;
}
} }
#endif #endif
return OGS_OK; return OGS_OK;
@@ -434,8 +450,14 @@ int ogs_proc_kill(ogs_proc_t *const process)
return OGS_ERROR; return OGS_ERROR;
} }
#else #else
if (kill(process->child, SIGKILL) == -1) { if (process->child) {
return OGS_ERROR; if (kill(process->child, SIGKILL) == -1) {
if (errno == ESRCH) {
/* No such process */
return OGS_OK;
}
return OGS_ERROR;
}
} }
#endif #endif

View File

@@ -73,6 +73,10 @@ typedef struct ogs_proc_s {
unsigned long dwProcessId; unsigned long dwProcessId;
#else #else
pid_t child; pid_t child;
// to force kill the right NF in tests if needed.
char *nf_name;
int index;
#endif #endif
} ogs_proc_t; } ogs_proc_t;

View File

@@ -754,7 +754,7 @@ static void check_multi_info(ogs_sbi_client_t *client)
} }
} else } else
ogs_warn("[%d] %s", res, conn->error); ogs_warn("%s (%d): %s", curl_easy_strerror(res), res, conn->error);
ogs_assert(conn->client_cb); ogs_assert(conn->client_cb);
if (res == CURLE_OK) if (res == CURLE_OK)

View File

@@ -45,7 +45,7 @@ cJSON *ogs_sbi_links_convertToJSON(ogs_sbi_links_t *links)
linksJSON = cJSON_CreateObject(); linksJSON = cJSON_CreateObject();
ogs_assert(linksJSON); ogs_assert(linksJSON);
cJSON_AddItemToObject(linksJSON, "items", itemsJSON); cJSON_AddItemToObject(linksJSON, "item", itemsJSON);
cJSON_AddItemToObject(linksJSON, "self", selfJSON); cJSON_AddItemToObject(linksJSON, "self", selfJSON);
cJSON_AddNumberToObject(linksJSON, "totalItemCount", cJSON_GetArraySize(itemsJSON)); cJSON_AddNumberToObject(linksJSON, "totalItemCount", cJSON_GetArraySize(itemsJSON));
@@ -73,9 +73,9 @@ ogs_sbi_links_t *ogs_sbi_links_parseFromJSON(cJSON *json)
return NULL; return NULL;
} }
_items = cJSON_GetObjectItemCaseSensitive(_links, "items"); _items = cJSON_GetObjectItemCaseSensitive(_links, "item");
if (!_items) { if (!_items) {
ogs_error("No items"); ogs_error("No item");
return NULL; return NULL;
} }

View File

@@ -78,6 +78,9 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_response_t *sbi_response = NULL; ogs_sbi_response_t *sbi_response = NULL;
ogs_sbi_message_t sbi_message; ogs_sbi_message_t sbi_message;
OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
ogs_sbi_discovery_option_t *discovery_option = NULL;
amf_sm_debug(e); amf_sm_debug(e);
ogs_assert(s); ogs_assert(s);
@@ -410,9 +413,11 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
CASE(OGS_SBI_HTTP_METHOD_GET) CASE(OGS_SBI_HTTP_METHOD_GET)
if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK) if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK)
amf_nnrf_handle_nf_discover(sbi_xact, &sbi_message); amf_nnrf_handle_nf_discover(sbi_xact, &sbi_message);
else else {
ogs_error("HTTP response error [%d]", ogs_error("HTTP response error [%d]",
sbi_message.res_status); sbi_message.res_status);
amf_nnrf_handle_failed_amf_discovery(sbi_xact);
}
break; break;
DEFAULT DEFAULT
@@ -737,6 +742,8 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
sbi_object_id <= OGS_MAX_POOL_ID); sbi_object_id <= OGS_MAX_POOL_ID);
service_type = sbi_xact->service_type; service_type = sbi_xact->service_type;
requester_nf_type = sbi_xact->requester_nf_type;
discovery_option = sbi_xact->discovery_option;
ogs_sbi_xact_remove(sbi_xact); ogs_sbi_xact_remove(sbi_xact);
@@ -754,6 +761,32 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_error("[%s:%s] Cannot receive SBI message", ogs_error("[%s:%s] Cannot receive SBI message",
amf_ue->supi, amf_ue->suci); amf_ue->supi, amf_ue->suci);
/*
* TS 23.502
* 4.2.2.2.2 General Registration
* If the SUCI is not provided by the UE nor retrieved from the old AMF the Identity Request
* procedure is initiated by AMF sending an Identity Request message to the UE requesting the SUCI.
*/
if (amf_ue->nas.message_type == OGS_NAS_5GS_REGISTRATION_REQUEST &&
amf_ue->nas.registration.value == OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL &&
requester_nf_type == OpenAPI_nf_type_AMF &&
discovery_option->guami_presence) {
amf_ue->amf_ue_context_transfer_state =
UE_CONTEXT_INITIAL_STATE;
if (!(AMF_UE_HAVE_SUCI(amf_ue) ||
AMF_UE_HAVE_SUPI(amf_ue))) {
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
rv = nas_5gs_send_identity_request(amf_ue);
ogs_expect(rv == OGS_OK);
ogs_assert(rv != OGS_ERROR);
break;
}
}
r = nas_5gs_send_gmm_reject_from_sbi(amf_ue, r = nas_5gs_send_gmm_reject_from_sbi(amf_ue,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT); OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);

View File

@@ -39,6 +39,7 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue,
ogs_nas_5gs_registration_request_t *registration_request) ogs_nas_5gs_registration_request_t *registration_request)
{ {
int served_tai_index = 0; int served_tai_index = 0;
int i;
uint8_t gmm_cause; uint8_t gmm_cause;
ran_ue_t *ran_ue = NULL; ran_ue_t *ran_ue = NULL;
@@ -164,6 +165,14 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue,
ogs_nas_to_plmn_id(&amf_ue->home_plmn_id, ogs_nas_to_plmn_id(&amf_ue->home_plmn_id,
&mobile_identity_suci->nas_plmn_id); &mobile_identity_suci->nas_plmn_id);
for (i = 0; i < amf_self()->num_of_served_guami; i++) {
if (!memcmp(&amf_ue->home_plmn_id,
&amf_self()->served_guami[i].plmn_id,
sizeof(amf_ue->home_plmn_id))) {
amf_ue->guami = &amf_self()->served_guami[i];
}
}
gmm_cause = gmm_cause_from_access_control(&amf_ue->home_plmn_id); gmm_cause = gmm_cause_from_access_control(&amf_ue->home_plmn_id);
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) { if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
ogs_error("Rejected by PLMN-ID access control"); ogs_error("Rejected by PLMN-ID access control");

View File

@@ -1342,8 +1342,6 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
nas_message = e->nas.message; nas_message = e->nas.message;
ogs_assert(nas_message); ogs_assert(nas_message);
ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
ogs_assert(ran_ue);
ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id); ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
if (!ran_ue) { if (!ran_ue) {
ogs_error("No NG Context SUPI[%s] NAS-Type[%d] " ogs_error("No NG Context SUPI[%s] NAS-Type[%d] "
@@ -1792,7 +1790,15 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(nas_message); ogs_assert(nas_message);
ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id); ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
ogs_assert(ran_ue); if (!ran_ue) {
ogs_error("No NG Context SUPI[%s] NAS-Type[%d] "
"RAN-UE-ID[%d:%p]",
amf_ue->supi, nas_message->gmm.h.message_type,
amf_ue->ran_ue_id, ran_ue_find_by_id(amf_ue->ran_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
h.type = e->nas.type; h.type = e->nas.type;
@@ -2151,7 +2157,15 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(nas_message); ogs_assert(nas_message);
ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id); ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
ogs_assert(ran_ue); if (!ran_ue) {
ogs_error("No NG Context SUPI[%s] NAS-Type[%d] "
"RAN-UE-ID[%d:%p]",
amf_ue->supi, nas_message->gmm.h.message_type,
amf_ue->ran_ue_id, ran_ue_find_by_id(amf_ue->ran_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
h.type = e->nas.type; h.type = e->nas.type;
@@ -2697,7 +2711,15 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(nas_message); ogs_assert(nas_message);
ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id); ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
ogs_assert(ran_ue); if (!ran_ue) {
ogs_error("No NG Context SUPI[%s] NAS-Type[%d] "
"RAN-UE-ID[%d:%p]",
amf_ue->supi, nas_message->gmm.h.message_type,
amf_ue->ran_ue_id, ran_ue_find_by_id(amf_ue->ran_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
h.type = e->nas.type; h.type = e->nas.type;
@@ -3002,7 +3024,15 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(nas_message); ogs_assert(nas_message);
ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id); ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
ogs_assert(ran_ue); if (!ran_ue) {
ogs_error("No NG Context SUPI[%s] NAS-Type[%d] "
"RAN-UE-ID[%d:%p]",
amf_ue->supi, nas_message->gmm.h.message_type,
amf_ue->ran_ue_id, ran_ue_find_by_id(amf_ue->ran_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
h.type = e->nas.type; h.type = e->nas.type;
@@ -3124,7 +3154,27 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
ogs_assert(sbi_message); ogs_assert(sbi_message);
ran_ue_t *ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id); ran_ue_t *ran_ue = ran_ue_find_by_id(amf_ue->ran_ue_id);
ogs_assert(ran_ue); if (!ran_ue) {
int i;
ogs_error("No NG Context SUPI[%s] Status[%d] RAN-UE-ID[%d:%p]",
amf_ue->supi, sbi_message->res_status,
amf_ue->ran_ue_id, ran_ue_find_by_id(amf_ue->ran_ue_id));
if (sbi_message->h.method)
ogs_error(" h.method[%s]", sbi_message->h.method);
if (sbi_message->h.uri)
ogs_error(" h.uri[%s]", sbi_message->h.uri);
if (sbi_message->h.service.name)
ogs_error(" h.service.name[%s]",
sbi_message->h.service.name);
if (sbi_message->h.api.version)
ogs_error(" h.api.version[%s]", sbi_message->h.api.version);
for (i = 0; i < OGS_SBI_MAX_NUM_OF_RESOURCE_COMPONENT &&
sbi_message->h.resource.component[i]; i++)
ogs_error(" h.resource.component[%s:%d]",
sbi_message->h.resource.component[i], i);
break;
}
SWITCH(sbi_message->h.service.name) SWITCH(sbi_message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH) CASE(OGS_SBI_SERVICE_NAME_NAUSF_AUTH)

View File

@@ -171,7 +171,6 @@ ogs_pkbuf_t *ngap_build_ng_setup_failure(
NGAP_NGSetupFailureIEs_t *ie = NULL; NGAP_NGSetupFailureIEs_t *ie = NULL;
NGAP_Cause_t *Cause = NULL; NGAP_Cause_t *Cause = NULL;
NGAP_TimeToWait_t *TimeToWait = NULL;
ogs_debug(" Group[%d] Cause[%d] TimeToWait[%ld]", ogs_debug(" Group[%d] Cause[%d] TimeToWait[%ld]",
group, (int)cause, time_to_wait); group, (int)cause, time_to_wait);
@@ -189,17 +188,6 @@ ogs_pkbuf_t *ngap_build_ng_setup_failure(
NGSetupFailure = &unsuccessfulOutcome->value.choice.NGSetupFailure; NGSetupFailure = &unsuccessfulOutcome->value.choice.NGSetupFailure;
if (time_to_wait > -1) {
ie = CALLOC(1, sizeof(NGAP_NGSetupFailureIEs_t));
ASN_SEQUENCE_ADD(&NGSetupFailure->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_TimeToWait;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_NGSetupFailureIEs__value_PR_TimeToWait;
TimeToWait = &ie->value.choice.TimeToWait;
}
ie = CALLOC(1, sizeof(NGAP_NGSetupFailureIEs_t)); ie = CALLOC(1, sizeof(NGAP_NGSetupFailureIEs_t));
ASN_SEQUENCE_ADD(&NGSetupFailure->protocolIEs, ie); ASN_SEQUENCE_ADD(&NGSetupFailure->protocolIEs, ie);
@@ -211,8 +199,16 @@ ogs_pkbuf_t *ngap_build_ng_setup_failure(
Cause->present = group; Cause->present = group;
Cause->choice.radioNetwork = cause; Cause->choice.radioNetwork = cause;
if (TimeToWait) if (time_to_wait > -1) {
*TimeToWait = time_to_wait; ie = CALLOC(1, sizeof(NGAP_NGSetupFailureIEs_t));
ASN_SEQUENCE_ADD(&NGSetupFailure->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_TimeToWait;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_NGSetupFailureIEs__value_PR_TimeToWait;
ie->value.choice.TimeToWait = time_to_wait;
}
return ogs_ngap_encode(&pdu); return ogs_ngap_encode(&pdu);
} }
@@ -1265,7 +1261,7 @@ ogs_pkbuf_t *ngap_build_ue_context_release_command(
&UE_NGAP_IDs->choice.aMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id); &UE_NGAP_IDs->choice.aMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id);
} else { } else {
UE_NGAP_IDs->present = NGAP_UE_NGAP_IDs_PR_uE_NGAP_ID_pair; UE_NGAP_IDs->present = NGAP_UE_NGAP_IDs_PR_uE_NGAP_ID_pair;
UE_NGAP_IDs->choice.uE_NGAP_ID_pair = UE_NGAP_IDs->choice.uE_NGAP_ID_pair =
CALLOC(1, sizeof(NGAP_UE_NGAP_ID_pair_t)); CALLOC(1, sizeof(NGAP_UE_NGAP_ID_pair_t));
asn_uint642INTEGER( asn_uint642INTEGER(
&UE_NGAP_IDs->choice.uE_NGAP_ID_pair->aMF_UE_NGAP_ID, &UE_NGAP_IDs->choice.uE_NGAP_ID_pair->aMF_UE_NGAP_ID,

View File

@@ -60,6 +60,7 @@ void amf_nnrf_handle_nf_discover(
SearchResult = recvmsg->SearchResult; SearchResult = recvmsg->SearchResult;
if (!SearchResult) { if (!SearchResult) {
ogs_error("No SearchResult"); ogs_error("No SearchResult");
amf_nnrf_handle_failed_amf_discovery(xact);
return; return;
} }
@@ -84,8 +85,38 @@ void amf_nnrf_handle_nf_discover(
if (!nf_instance) { if (!nf_instance) {
switch(sbi_object->type) { switch(sbi_object->type) {
case OGS_SBI_OBJ_UE_TYPE: case OGS_SBI_OBJ_UE_TYPE:
ogs_error("[%s] (NF discover) No [%s]", amf_ue->suci, amf_ue = (amf_ue_t *)sbi_object;
ogs_assert(amf_ue);
ogs_warn("[%s] (NF discover) No [%s]", amf_ue->suci,
ogs_sbi_service_type_to_name(service_type)); ogs_sbi_service_type_to_name(service_type));
/*
* TS 23.502
* 4.2.2.2.2 General Registration
* If the SUCI is not provided by the UE nor retrieved from the old AMF the Identity Request
* procedure is initiated by AMF sending an Identity Request message to the UE requesting the SUCI.
*/
if (amf_ue->nas.message_type == OGS_NAS_5GS_REGISTRATION_REQUEST &&
amf_ue->nas.registration.value == OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL &&
requester_nf_type == OpenAPI_nf_type_AMF &&
discovery_option->guami_presence) {
amf_ue->amf_ue_context_transfer_state =
UE_CONTEXT_INITIAL_STATE;
ogs_sbi_xact_remove(xact);
if (!(AMF_UE_HAVE_SUCI(amf_ue) ||
AMF_UE_HAVE_SUPI(amf_ue))) {
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
r = nas_5gs_send_identity_request(amf_ue);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
break;
}
}
r = nas_5gs_send_gmm_reject_from_sbi(amf_ue, r = nas_5gs_send_gmm_reject_from_sbi(amf_ue,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT); OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT);
ogs_expect(r == OGS_OK); ogs_expect(r == OGS_OK);
@@ -124,3 +155,62 @@ void amf_nnrf_handle_nf_discover(
ogs_expect(true == amf_sbi_send_request(nf_instance, xact)); ogs_expect(true == amf_sbi_send_request(nf_instance, xact));
} }
void amf_nnrf_handle_failed_amf_discovery(
ogs_sbi_xact_t *sbi_xact)
{
int r;
OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
ogs_sbi_discovery_option_t *discovery_option = NULL;
ogs_sbi_service_type_e service_type = OGS_SBI_SERVICE_TYPE_NULL;
ogs_sbi_object_t *sbi_object = NULL;
amf_ue_t *amf_ue = NULL;
ogs_assert(sbi_xact);
sbi_object = sbi_xact->sbi_object;
ogs_assert(sbi_object);
service_type = sbi_xact->service_type;
ogs_assert(service_type);
requester_nf_type = sbi_xact->requester_nf_type;
ogs_assert(requester_nf_type);
discovery_option = sbi_xact->discovery_option;
ogs_assert(sbi_object->type > OGS_SBI_OBJ_BASE &&
sbi_object->type < OGS_SBI_OBJ_TOP);
if (sbi_object->type == OGS_SBI_OBJ_UE_TYPE) {
amf_ue = (amf_ue_t *)sbi_object;
ogs_assert(amf_ue);
/*
* TS 23.502
* 4.2.2.2.2 General Registration
* If the SUCI is not provided by the UE nor retrieved from the old AMF the Identity Request
* procedure is initiated by AMF sending an Identity Request message to the UE requesting the SUCI.
*/
if (amf_ue->nas.message_type == OGS_NAS_5GS_REGISTRATION_REQUEST &&
amf_ue->nas.registration.value == OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL &&
requester_nf_type == OpenAPI_nf_type_AMF &&
discovery_option->guami_presence) {
amf_ue->amf_ue_context_transfer_state =
UE_CONTEXT_INITIAL_STATE;
ogs_sbi_xact_remove(sbi_xact);
if (!(AMF_UE_HAVE_SUCI(amf_ue) ||
AMF_UE_HAVE_SUPI(amf_ue))) {
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
r = nas_5gs_send_identity_request(amf_ue);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
}
}
}
return;
}

View File

@@ -28,6 +28,8 @@ extern "C" {
void amf_nnrf_handle_nf_discover( void amf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg); ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg);
void amf_nnrf_handle_failed_amf_discovery(
ogs_sbi_xact_t *sbi_xact);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1106,7 +1106,17 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id); enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id);
ogs_assert(enb_ue); if (!enb_ue) {
ogs_error("No S1 Context IMSI[%s] NAS-Type[%d] "
"ENB-UE-ID[%d:%d][%p:%p]",
mme_ue->imsi_bcd, message->emm.h.message_type,
e->enb_ue_id, mme_ue->enb_ue_id,
enb_ue_find_by_id(e->enb_ue_id),
enb_ue_find_by_id(mme_ue->enb_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
switch (message->emm.h.message_type) { switch (message->emm.h.message_type) {
case OGS_NAS_EPS_AUTHENTICATION_RESPONSE: case OGS_NAS_EPS_AUTHENTICATION_RESPONSE:
@@ -1288,7 +1298,17 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id); enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id);
ogs_assert(enb_ue); if (!enb_ue) {
ogs_error("No S1 Context IMSI[%s] NAS-Type[%d] "
"ENB-UE-ID[%d:%d][%p:%p]",
mme_ue->imsi_bcd, message->emm.h.message_type,
e->enb_ue_id, mme_ue->enb_ue_id,
enb_ue_find_by_id(e->enb_ue_id),
enb_ue_find_by_id(mme_ue->enb_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
if (message->emm.h.security_header_type if (message->emm.h.security_header_type
== OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) { == OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) {
@@ -1528,7 +1548,17 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id); enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id);
ogs_assert(enb_ue); if (!enb_ue) {
ogs_error("No S1 Context IMSI[%s] NAS-Type[%d] "
"ENB-UE-ID[%d:%d][%p:%p]",
mme_ue->imsi_bcd, message->emm.h.message_type,
e->enb_ue_id, mme_ue->enb_ue_id,
enb_ue_find_by_id(e->enb_ue_id),
enb_ue_find_by_id(mme_ue->enb_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
xact_count = mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR); xact_count = mme_ue_xact_count(mme_ue, OGS_GTP_LOCAL_ORIGINATOR);
@@ -1820,7 +1850,17 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(message); ogs_assert(message);
enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id); enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id);
ogs_assert(enb_ue); if (!enb_ue) {
ogs_error("No S1 Context IMSI[%s] NAS-Type[%d] "
"ENB-UE-ID[%d:%d][%p:%p]",
mme_ue->imsi_bcd, message->emm.h.message_type,
e->enb_ue_id, mme_ue->enb_ue_id,
enb_ue_find_by_id(e->enb_ue_id),
enb_ue_find_by_id(mme_ue->enb_ue_id));
ogs_assert(e->pkbuf);
ogs_log_hexdump(OGS_LOG_ERROR, e->pkbuf->data, e->pkbuf->len);
break;
}
h.type = e->nas_type; h.type = e->nas_type;

View File

@@ -1197,14 +1197,19 @@ void smf_sess_select_upf(smf_sess_t *sess)
ogs_pfcp_self()->pfcp_node = ogs_pfcp_self()->pfcp_node =
ogs_list_last(&ogs_pfcp_self()->pfcp_peer_list); ogs_list_last(&ogs_pfcp_self()->pfcp_peer_list);
/* setup GTP session with selected UPF */ if (ogs_pfcp_self()->pfcp_node) {
ogs_pfcp_self()->pfcp_node = /* setup GTP session with selected UPF */
selected_upf_node(ogs_pfcp_self()->pfcp_node, sess); ogs_pfcp_self()->pfcp_node =
ogs_assert(ogs_pfcp_self()->pfcp_node); selected_upf_node(ogs_pfcp_self()->pfcp_node, sess);
OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->pfcp_node); ogs_assert(ogs_pfcp_self()->pfcp_node);
ogs_debug("UE using UPF on IP %s", OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->pfcp_node);
ogs_sockaddr_to_string_static( ogs_debug("UE using UPF on IP %s",
ogs_pfcp_self()->pfcp_node->addr_list)); ogs_sockaddr_to_string_static(
ogs_pfcp_self()->pfcp_node->addr_list));
} else {
ogs_error("No suitable UPF found for session");
ogs_assert(sess->pfcp_node == NULL);
}
} }
smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type) smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type)

View File

@@ -284,10 +284,19 @@ uint8_t smf_gn_handle_create_pdp_context_request(
/* Select PGW based on UE Location Information */ /* Select PGW based on UE Location Information */
smf_sess_select_upf(sess); smf_sess_select_upf(sess);
/* Check if UPF selection was successful */
if (!sess->pfcp_node) {
ogs_error("[%s:%s] No UPF available for session",
smf_ue->imsi_bcd, sess->session.name);
return OGS_GTP1_CAUSE_SYSTEM_FAILURE;
}
/* Check if selected PGW is associated with SMF */ /* Check if selected PGW is associated with SMF */
ogs_assert(sess->pfcp_node); if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) {
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) ogs_error("[%s:%s] selected UPF is not assocated with SMF",
smf_ue->imsi_bcd, sess->session.name);
return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE; return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
}
if ((pfcp_cause = smf_sess_set_ue_ip(sess)) != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { if ((pfcp_cause = smf_sess_set_ue_ip(sess)) != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
cause_value = gtp_cause_from_pfcp(pfcp_cause, 1); cause_value = gtp_cause_from_pfcp(pfcp_cause, 1);

View File

@@ -525,8 +525,12 @@ int ngap_handle_path_switch_request_transfer(
OGS_PFCP_MODIFY_XN_HANDOVER|OGS_PFCP_MODIFY_END_MARKER, OGS_PFCP_MODIFY_XN_HANDOVER|OGS_PFCP_MODIFY_END_MARKER,
0, 0)); 0, 0));
} else { } else {
/* ACTIVATED Is NOT Included in RESPONSE */ ogs_pkbuf_t *n2smbuf =
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream)); ngap_build_path_switch_request_ack_transfer(sess);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_n2smbuf(sess, stream,
OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK, n2smbuf);
} }
rv = OGS_OK; rv = OGS_OK;

View File

@@ -477,8 +477,14 @@ bool smf_npcf_smpolicycontrol_handle_create(
/* Select UPF based on UE Location Information */ /* Select UPF based on UE Location Information */
smf_sess_select_upf(sess); smf_sess_select_upf(sess);
/* Check if UPF selection was successful */
if (!sess->pfcp_node) {
ogs_error("[%s:%d] No UPF available for session",
smf_ue->supi, sess->psi);
return false;
}
/* Check if selected UPF is associated with SMF */ /* Check if selected UPF is associated with SMF */
ogs_assert(sess->pfcp_node);
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) { if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) {
ogs_error("[%s:%d] No associated UPF", smf_ue->supi, sess->psi); ogs_error("[%s:%d] No associated UPF", smf_ue->supi, sess->psi);
return false; return false;

View File

@@ -261,10 +261,18 @@ uint8_t smf_s5c_handle_create_session_request(
/* Select PGW based on UE Location Information */ /* Select PGW based on UE Location Information */
smf_sess_select_upf(sess); smf_sess_select_upf(sess);
if (!sess->pfcp_node) {
ogs_error("[%s:%s] No UPF available for session",
smf_ue->imsi_bcd, sess->session.name);
return OGS_GTP2_CAUSE_SYSTEM_FAILURE;
}
/* Check if selected PGW is associated with SMF */ /* Check if selected PGW is associated with SMF */
ogs_assert(sess->pfcp_node); if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) {
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, smf_pfcp_state_associated)) ogs_error("[%s:%s] selected UPF is not assocated with SMF",
smf_ue->imsi_bcd, sess->session.name);
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING; return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
}
/* UE IP Address */ /* UE IP Address */
paa = req->pdn_address_allocation.data; paa = req->pdn_address_allocation.data;

View File

@@ -42,7 +42,7 @@ static void run_threads(const char *nf_name, int count,
{ {
int i; int i;
threads[0] = test_child_create(nf_name, argv_out); threads[0] = test_child_create(nf_name, 0, argv_out);
for (i = 1; i < count; i++) { for (i = 1; i < count; i++) {
const char *idx_string = NULL;; const char *idx_string = NULL;;
@@ -62,7 +62,7 @@ static void run_threads(const char *nf_name, int count,
argv_out[argv_out_idx + 1] = idx_string; argv_out[argv_out_idx + 1] = idx_string;
argv_out[argv_out_idx + 2] = NULL; argv_out[argv_out_idx + 2] = NULL;
threads[i] = test_child_create(nf_name, argv_out); threads[i] = test_child_create(nf_name, i, argv_out);
} }
// reset argv_out and remove the added "-k" parameter // reset argv_out and remove the added "-k" parameter
@@ -90,11 +90,11 @@ int app_initialize(const char *const argv[])
} }
if (ogs_global_conf()->parameter.no_nrf == 0) if (ogs_global_conf()->parameter.no_nrf == 0)
nrf_thread = test_child_create("nrf", argv_out); nrf_thread = test_child_create("nrf", 0, argv_out);
if (ogs_global_conf()->parameter.no_scp == 0) if (ogs_global_conf()->parameter.no_scp == 0)
scp_thread = test_child_create("scp", argv_out); scp_thread = test_child_create("scp", 0, argv_out);
if (ogs_global_conf()->parameter.no_sepp == 0) if (ogs_global_conf()->parameter.no_sepp == 0)
sepp_thread = test_child_create("sepp", argv_out); sepp_thread = test_child_create("sepp", 0, argv_out);
if (ogs_global_conf()->parameter.no_upf == 0) if (ogs_global_conf()->parameter.no_upf == 0)
run_threads("upf", ogs_global_conf()->parameter.upf_count, run_threads("upf", ogs_global_conf()->parameter.upf_count,
@@ -139,29 +139,55 @@ void app_terminate(void)
int i; int i;
for (i = 0; i < OGS_MAX_NF_INSTANCES; i++) { for (i = 0; i < OGS_MAX_NF_INSTANCES; i++) {
if (amf_threads[i]) if (amf_threads[i]) {
ogs_thread_destroy(amf_threads[i]); ogs_thread_destroy(amf_threads[i]);
if (smf_threads[i]) amf_threads[i] = NULL;
}
if (smf_threads[i]) {
ogs_thread_destroy(smf_threads[i]); ogs_thread_destroy(smf_threads[i]);
if (upf_threads[i]) smf_threads[i] = NULL;
}
if (upf_threads[i]) {
ogs_thread_destroy(upf_threads[i]); ogs_thread_destroy(upf_threads[i]);
if (udr_threads[i]) upf_threads[i] = NULL;
}
if (udr_threads[i]) {
ogs_thread_destroy(udr_threads[i]); ogs_thread_destroy(udr_threads[i]);
if (nssf_threads[i]) udr_threads[i] = NULL;
}
if (nssf_threads[i]) {
ogs_thread_destroy(nssf_threads[i]); ogs_thread_destroy(nssf_threads[i]);
if (bsf_threads[i]) nssf_threads[i] = NULL;
}
if (bsf_threads[i]) {
ogs_thread_destroy(bsf_threads[i]); ogs_thread_destroy(bsf_threads[i]);
if (pcf_threads[i]) bsf_threads[i] = NULL;
}
if (pcf_threads[i]) {
ogs_thread_destroy(pcf_threads[i]); ogs_thread_destroy(pcf_threads[i]);
if (udm_threads[i]) pcf_threads[i] = NULL;
}
if (udm_threads[i]) {
ogs_thread_destroy(udm_threads[i]); ogs_thread_destroy(udm_threads[i]);
if (ausf_threads[i]) udm_threads[i] = NULL;
}
if (ausf_threads[i]) {
ogs_thread_destroy(ausf_threads[i]); ogs_thread_destroy(ausf_threads[i]);
ausf_threads[i] = NULL;
}
}
if (sepp_thread) {
ogs_thread_destroy(sepp_thread);
sepp_thread = NULL;
}
if (scp_thread) {
ogs_thread_destroy(scp_thread);
scp_thread = NULL;
}
if (nrf_thread) {
ogs_thread_destroy(nrf_thread);
nrf_thread = NULL;
} }
if (sepp_thread) ogs_thread_destroy(sepp_thread);
if (scp_thread) ogs_thread_destroy(scp_thread);
if (nrf_thread) ogs_thread_destroy(nrf_thread);
} }
void test_5gc_init(void) void test_5gc_init(void)

View File

@@ -58,43 +58,43 @@ int app_initialize(const char *const argv[])
} }
if (ogs_global_conf()->parameter.no_nrf == 0) if (ogs_global_conf()->parameter.no_nrf == 0)
nrf_thread = test_child_create("nrf", argv_out); nrf_thread = test_child_create("nrf", 0, argv_out);
if (ogs_global_conf()->parameter.no_scp == 0) if (ogs_global_conf()->parameter.no_scp == 0)
scp_thread = test_child_create("scp", argv_out); scp_thread = test_child_create("scp", 0, argv_out);
if (ogs_global_conf()->parameter.no_sepp == 0) if (ogs_global_conf()->parameter.no_sepp == 0)
sepp_thread = test_child_create("sepp", argv_out); sepp_thread = test_child_create("sepp", 0, argv_out);
if (ogs_global_conf()->parameter.no_hss == 0) if (ogs_global_conf()->parameter.no_hss == 0)
hss_thread = test_child_create("hss", argv_out); hss_thread = test_child_create("hss", 0, argv_out);
if (ogs_global_conf()->parameter.no_pcrf == 0) if (ogs_global_conf()->parameter.no_pcrf == 0)
pcrf_thread = test_child_create("pcrf", argv_out); pcrf_thread = test_child_create("pcrf", 0, argv_out);
if (ogs_global_conf()->parameter.no_upf == 0) if (ogs_global_conf()->parameter.no_upf == 0)
upf_thread = test_child_create("upf", argv_out); upf_thread = test_child_create("upf", 0, argv_out);
if (ogs_global_conf()->parameter.no_sgwu == 0) if (ogs_global_conf()->parameter.no_sgwu == 0)
sgwu_thread = test_child_create("sgwu", argv_out); sgwu_thread = test_child_create("sgwu", 0, argv_out);
if (ogs_global_conf()->parameter.no_smf == 0) if (ogs_global_conf()->parameter.no_smf == 0)
smf_thread = test_child_create("smf", argv_out); smf_thread = test_child_create("smf", 0, argv_out);
if (ogs_global_conf()->parameter.no_sgwc == 0) if (ogs_global_conf()->parameter.no_sgwc == 0)
sgwc_thread = test_child_create("sgwc", argv_out); sgwc_thread = test_child_create("sgwc", 0, argv_out);
if (ogs_global_conf()->parameter.no_mme == 0) if (ogs_global_conf()->parameter.no_mme == 0)
mme_thread = test_child_create("mme", argv_out); mme_thread = test_child_create("mme", 0, argv_out);
if (ogs_global_conf()->parameter.no_amf == 0) if (ogs_global_conf()->parameter.no_amf == 0)
amf_thread = test_child_create("amf", argv_out); amf_thread = test_child_create("amf", 0, argv_out);
if (ogs_global_conf()->parameter.no_ausf == 0) if (ogs_global_conf()->parameter.no_ausf == 0)
ausf_thread = test_child_create("ausf", argv_out); ausf_thread = test_child_create("ausf", 0, argv_out);
if (ogs_global_conf()->parameter.no_udm == 0) if (ogs_global_conf()->parameter.no_udm == 0)
udm_thread = test_child_create("udm", argv_out); udm_thread = test_child_create("udm", 0, argv_out);
if (ogs_global_conf()->parameter.no_pcf == 0) if (ogs_global_conf()->parameter.no_pcf == 0)
pcf_thread = test_child_create("pcf", argv_out); pcf_thread = test_child_create("pcf", 0, argv_out);
if (ogs_global_conf()->parameter.no_nssf == 0) if (ogs_global_conf()->parameter.no_nssf == 0)
nssf_thread = test_child_create("nssf", argv_out); nssf_thread = test_child_create("nssf", 0, argv_out);
if (ogs_global_conf()->parameter.no_bsf == 0) if (ogs_global_conf()->parameter.no_bsf == 0)
bsf_thread = test_child_create("bsf", argv_out); bsf_thread = test_child_create("bsf", 0, argv_out);
if (ogs_global_conf()->parameter.no_udr == 0) if (ogs_global_conf()->parameter.no_udr == 0)
udr_thread = test_child_create("udr", argv_out); udr_thread = test_child_create("udr", 0, argv_out);
/* /*
* Wait for all sockets listening * Wait for all sockets listening

View File

@@ -48,22 +48,22 @@ int app_initialize(const char *const argv[])
} }
if (ogs_global_conf()->parameter.no_hss == 0) if (ogs_global_conf()->parameter.no_hss == 0)
hss_thread = test_child_create("hss", argv_out); hss_thread = test_child_create("hss", 0, argv_out);
if (ogs_global_conf()->parameter.no_pcrf == 0) if (ogs_global_conf()->parameter.no_pcrf == 0)
pcrf_thread = test_child_create("pcrf", argv_out); pcrf_thread = test_child_create("pcrf", 0, argv_out);
if (ogs_global_conf()->parameter.no_upf == 0) if (ogs_global_conf()->parameter.no_upf == 0)
upf_thread = test_child_create("upf", argv_out); upf_thread = test_child_create("upf", 0, argv_out);
if (ogs_global_conf()->parameter.no_sgwu == 0) if (ogs_global_conf()->parameter.no_sgwu == 0)
sgwu_thread = test_child_create("sgwu", argv_out); sgwu_thread = test_child_create("sgwu", 0, argv_out);
if (ogs_global_conf()->parameter.no_smf == 0) if (ogs_global_conf()->parameter.no_smf == 0)
smf_thread = test_child_create("smf", argv_out); smf_thread = test_child_create("smf", 0, argv_out);
if (ogs_global_conf()->parameter.no_sgwc == 0) if (ogs_global_conf()->parameter.no_sgwc == 0)
sgwc_thread = test_child_create("sgwc", argv_out); sgwc_thread = test_child_create("sgwc", 0, argv_out);
if (ogs_global_conf()->parameter.no_mme == 0) if (ogs_global_conf()->parameter.no_mme == 0)
mme_thread = test_child_create("mme", argv_out); mme_thread = test_child_create("mme", 0, argv_out);
/* /*
* Wait for all sockets listening * Wait for all sockets listening

View File

@@ -85,7 +85,8 @@ static int process_num = 0;
static void child_main(void *data) static void child_main(void *data)
{ {
const char **commandLine = data; thread_data_t *thread_data = data;
const char **commandLine = thread_data->commandLine;
ogs_proc_t *current = NULL; ogs_proc_t *current = NULL;
FILE *out = NULL; FILE *out = NULL;
char buf[OGS_HUGE_LEN]; char buf[OGS_HUGE_LEN];
@@ -93,6 +94,10 @@ static void child_main(void *data)
current = &process[process_num++]; current = &process[process_num++];
// get name and index of NF into the process.
current->nf_name = ogs_strdup(thread_data->nf_name);
current->index = thread_data->index;
if (process_num > MAX_CHILD_PROCESS) { if (process_num > MAX_CHILD_PROCESS) {
ogs_fatal("Process limit reached"); ogs_fatal("Process limit reached");
ogs_assert_if_reached(); ogs_assert_if_reached();
@@ -118,13 +123,17 @@ static void child_main(void *data)
ogs_assert(ret == 0); ogs_assert(ret == 0);
} }
ogs_thread_t *test_child_create(const char *name, const char *const argv[]) ogs_thread_t *test_child_create(const char *name, int index, const char *const argv[])
{ {
ogs_thread_t *child = NULL; ogs_thread_t *child = NULL;
thread_data_t thread_data;
const char *commandLine[OGS_ARG_MAX]; const char *commandLine[OGS_ARG_MAX];
int i = 0; int i = 0;
char command[OGS_MAX_FILEPATH_LEN]; char command[OGS_MAX_FILEPATH_LEN];
memset(&thread_data, 0, sizeof(thread_data));
while(argv[i] && i < 32) { while(argv[i] && i < 32) {
commandLine[i] = argv[i]; commandLine[i] = argv[i];
i++; i++;
@@ -137,7 +146,11 @@ ogs_thread_t *test_child_create(const char *name, const char *const argv[])
name, OGS_DIR_SEPARATOR_S "open5gs-", name); name, OGS_DIR_SEPARATOR_S "open5gs-", name);
commandLine[0] = command; commandLine[0] = command;
child = ogs_thread_create(child_main, commandLine); thread_data.commandLine = commandLine;
thread_data.nf_name = name;
thread_data.index = index;
child = ogs_thread_create(child_main, &thread_data);
ogs_msleep(50); ogs_msleep(50);
@@ -150,6 +163,26 @@ void test_child_terminate(void)
ogs_proc_t *current = NULL; ogs_proc_t *current = NULL;
for (i = 0; i < process_num; i++) { for (i = 0; i < process_num; i++) {
current = &process[i]; current = &process[i];
ogs_proc_terminate(current);
if (current->stdin_file != 0 && current->child != 0) {
ogs_proc_terminate(current);
}
} }
} }
void test_child_terminate_with_name(char *name, int index)
{
int i;
ogs_proc_t *current = NULL;
for (i = 0; i < process_num; i++) {
current = &process[i];
if (!strcmp(current->nf_name, name) &&
current->index == index &&
current->stdin_file != 0 &&
current->child != 0) {
ogs_proc_terminate(current);
break;
}
}
}

View File

@@ -28,10 +28,18 @@
extern "C" { extern "C" {
#endif #endif
typedef struct {
const char **commandLine;
const char *nf_name;
int index;
pid_t child;
} thread_data_t;
void test_app_run(int argc, const char *const argv[], void test_app_run(int argc, const char *const argv[],
const char *name, void (*init)(const char * const argv[])); const char *name, void (*init)(const char * const argv[]));
void test_child_terminate(void); void test_child_terminate(void);
ogs_thread_t *test_child_create(const char *name, const char *const argv[]); void test_child_terminate_with_name(char *name, int index);
ogs_thread_t *test_child_create(const char *name, int index, const char *const argv[]);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -19,7 +19,7 @@
#include "test-common.h" #include "test-common.h"
static void test1_func(abts_case *tc, void *data) static void test_two_qos_flows(abts_case *tc, void *data)
{ {
int rv; int rv;
ogs_socknode_t *ngap1, *ngap2; ogs_socknode_t *ngap1, *ngap2;
@@ -436,11 +436,349 @@ static void test1_func(abts_case *tc, void *data)
test_ue_remove(test_ue); test_ue_remove(test_ue);
} }
static void test_keep_tunnel(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *ngap1, *ngap2;
ogs_socknode_t *gtpu1, *gtpu2;
ogs_pkbuf_t *gmmbuf;
ogs_pkbuf_t *gsmbuf;
ogs_pkbuf_t *nasbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_ngap_message_t message;
int i;
uint8_t tmp[OGS_HUGE_LEN];
char *_gtp_payload = "34ff0024"
"0000000100000085 010002004500001c 0c0b000040015a7a 0a2d00010a2d0002"
"00000964cd7c291f";
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t *test_ue = NULL;
test_sess_t *sess = NULL;
test_bearer_t *qos_flow = NULL;
bson_t *doc = NULL;
/* 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, "0000203190");
ogs_assert(test_ue);
test_ue->nr_cgi.cell_id = 0x40001;
test_ue->nas.registration.tsc = 0;
test_ue->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
test_ue->nas.registration.follow_on_request = 1;
test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca";
/* Two gNB connects to AMF */
ngap1 = testngap_client(1, AF_INET);
ABTS_PTR_NOTNULL(tc, ngap1);
ngap2 = testngap_client(1, AF_INET);
ABTS_PTR_NOTNULL(tc, ngap2);
/* Two gNB connects to UPF */
gtpu1 = test_gtpu_server(1, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu1);
gtpu2 = test_gtpu_server(2, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu2);
/* NG-Setup Reqeust/Response for Source gNB */
sendbuf = testngap_build_ng_setup_request(0x4000, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* NG-Setup Reqeust/Response for Target gNB */
sendbuf = testngap_build_ng_setup_request(0x4001, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
recvbuf = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, 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));
/* Send Registration request */
test_ue->registration_request_param.guti = 1;
gmmbuf = testgmm_build_registration_request(test_ue, NULL, false, false);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue->registration_request_param.gmm_capability = 1;
test_ue->registration_request_param.s1_ue_network_capability = 1;
test_ue->registration_request_param.requested_nssai = 1;
test_ue->registration_request_param.last_visited_registered_tai = 1;
test_ue->registration_request_param.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(test_ue, NULL, false, false);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf,
NGAP_RRCEstablishmentCause_mo_Signalling, false, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Identity request */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send Identity response */
gmmbuf = testgmm_build_identity_response(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Authentication request */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send Authentication response */
gmmbuf = testgmm_build_authentication_response(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode command */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send Security mode complete */
gmmbuf = testgmm_build_security_mode_complete(test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive InitialContextSetupRequest +
* Registration accept */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_InitialContextSetup,
test_ue->ngap_procedure_code);
/* Send UERadioCapabilityInfoIndication */
sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send InitialContextSetupResponse */
sendbuf = testngap_build_initial_context_setup_response(test_ue, false);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send PDU session establishment request */
sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5);
ogs_assert(sess);
sess->ul_nas_transport_param.request_type =
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;
sess->ul_nas_transport_param.dnn = 1;
sess->ul_nas_transport_param.s_nssai = 1;
sess->pdu_session_establishment_param.ssc_mode = 1;
sess->pdu_session_establishment_param.epco = 1;
gsmbuf = testgsm_build_pdu_session_establishment_request(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDUSessionResourceSetupRequest +
* DL NAS transport +
* PDU session establishment accept */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_PDUSessionResourceSetup,
test_ue->ngap_procedure_code);
/* Send GTP-U ICMP Packet */
qos_flow = test_qos_flow_find_by_qfi(sess, 1);
ogs_assert(qos_flow);
rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send PDUSessionResourceSetupResponse */
sendbuf = testngap_sess_build_pdu_session_resource_setup_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu1);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu1, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu1);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send Path Switch Request */
test_ue->nr_cgi.cell_id = 0x40002;
test_ue->ran_ue_ngap_id++;
sess->gnb_n3_addr = test_self()->gnb2_addr;
sendbuf = testngap_build_path_switch_request(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive End Mark */
recvbuf = test_gtpu_read(gtpu1);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Receive Path Switch Ack */
recvbuf = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
qos_flow = test_qos_flow_find_by_qfi(sess, 1);
ogs_assert(qos_flow);
rv = test_gtpu_send_ping(gtpu2, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu2);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send Path Switch Request */
test_ue->nr_cgi.cell_id = 0x40001;
test_ue->ran_ue_ngap_id++;
#if 0 /* Use the same gNB N3 Address */
sess->gnb_n3_addr = test_self()->gnb1_addr;
#endif
sendbuf = testngap_build_path_switch_request(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Path Switch Ack */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
qos_flow = test_qos_flow_find_by_qfi(sess, 1);
ogs_assert(qos_flow);
rv = test_gtpu_send_ping(gtpu2, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu2);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send UEContextReleaseRequest */
sendbuf = testngap_build_ue_context_release_request(test_ue,
NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity,
true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UEContextReleaseCommand */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_UEContextRelease,
test_ue->ngap_procedure_code);
/* Send UEContextReleaseComplete */
sendbuf = testngap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(300);
/********** Remove Subscriber in Database */
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue));
/* Two gNB disonncect from UPF */
testgnb_gtpu_close(gtpu1);
testgnb_gtpu_close(gtpu2);
/* Two gNB disonncect from AMF */
testgnb_ngap_close(ngap1);
testgnb_ngap_close(ngap2);
/* Clear Test UE Context */
test_ue_remove(test_ue);
}
abts_suite *test_5gc_xn(abts_suite *suite) abts_suite *test_5gc_xn(abts_suite *suite)
{ {
suite = ADD_SUITE(suite) suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func, NULL); abts_run_test(suite, test_two_qos_flows, NULL);
abts_run_test(suite, test_keep_tunnel, NULL);
return suite; return suite;
} }

View File

@@ -0,0 +1,66 @@
/*
* 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-app.h"
abts_suite * test_ue_context_transfer_error_case(abts_suite *suite);
const struct testlist {
abts_suite *(*func)(abts_suite *suite);
} alltests_error[] = {
{test_ue_context_transfer_error_case},
{NULL},
};
static void terminate(void)
{
ogs_msleep(50);
test_child_terminate();
app_terminate();
test_5gc_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_5gc_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, "transfer-error-case.yaml", initialize);
for (i = 0; alltests_error[i].func; i++)
suite = alltests_error[i].func(suite);
return abts_report(suite);
}

View File

@@ -63,4 +63,4 @@ int main(int argc, const char *const argv[])
suite = alltests[i].func(suite); suite = alltests[i].func(suite);
return abts_report(suite); return abts_report(suite);
} }

View File

@@ -20,9 +20,20 @@ testapp_transfer_sources = files('''
ue-context-transfer-test.c ue-context-transfer-test.c
'''.split()) '''.split())
testapp_transfer_error_sources = files('''
abts-error-main.c
ue-context-transfer-error-case-test.c
'''.split())
testapp_transfer_exe = executable('transfer', testapp_transfer_exe = executable('transfer',
sources : testapp_transfer_sources, sources : testapp_transfer_sources,
c_args : testunit_core_cc_flags, c_args : testunit_core_cc_flags,
dependencies : libtest5gc_dep) dependencies : libtest5gc_dep)
testapp_transfer_error_exe = executable('transfer-error',
sources : testapp_transfer_error_sources,
c_args : testunit_core_cc_flags,
dependencies : libtest5gc_dep)
test('transfer', testapp_transfer_exe, is_parallel : false, suite: '5gc') test('transfer', testapp_transfer_exe, is_parallel : false, suite: '5gc')
test('transfer-error', testapp_transfer_error_exe, is_parallel : false, suite: '5gc')

View File

@@ -0,0 +1,681 @@
/*
* Copyright (C) 2019,2020 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"
static void test1_func_error(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *ngap1, *ngap2;
ogs_socknode_t *gtpu1, *gtpu2;
ogs_pkbuf_t *gmmbuf;
ogs_pkbuf_t *gsmbuf;
ogs_pkbuf_t *nasbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_pkbuf_t *recvbuf_target;
ogs_ngap_message_t message;
int i;
uint8_t tmp[OGS_HUGE_LEN];
char *_gtp_payload = "34ff0024"
"0000000100000085 010002004500001c 0c0b000040015a7a 0a2d00010a2d0002"
"00000964cd7c291f";
#define NUM_OF_TEST_UE_1 1
/* ERROR case simulation, when no SCP in 5G core */
/* Test: 1 UE, Old AMF, Target AMF,
* register to Old AMF, PDU session establishment, session release, deregister,
* old AMF is killed (main point of this test)
* send registation request to Target AMF with Old AMF's 5G GUTI,
* UE context transfer can not be finished because old AMF is not found
* new AMF sends Identity Request and registration continues
* PDU session establishment, session release, deregister
*/
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t *test_ue[NUM_OF_TEST_UE_1];
test_ue_t *test_ue_target[NUM_OF_TEST_UE_1];
test_sess_t *sess = NULL;
test_bearer_t *qos_flow = NULL;
bson_t *doc = NULL;
/* First gNB connects to Target AMF */
ngap2 = testngap_client(2, AF_INET);
ABTS_PTR_NOTNULL(tc, ngap2);
/* Second gNB connects to Old AMF */
ngap1 = testngap_client(1, AF_INET);
ABTS_PTR_NOTNULL(tc, ngap1);
/* Two gNB connects to UPF */
gtpu1 = test_gtpu_server(1, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu1);
gtpu2 = test_gtpu_server(2, AF_INET);
ABTS_PTR_NOTNULL(tc, gtpu2);
/* NG-Setup Reqeust/Response for Target gNB - with Target AMF */
sendbuf = testngap_build_ng_setup_request(0x4000, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
recvbuf = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* NG-Setup Reqeust/Response for Source gNB - with Old AMF */
sendbuf = testngap_build_ng_setup_request(0x4001, 28);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
recvbuf_target = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue, recvbuf_target);
/* Register to Old AMF */
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
const char *scheme_output[] = {
"0000000001",
"0000000002",
"0000000003",
"0000000004",
"0000000005",
};
/* 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[i] = test_ue_add_by_suci(
&mobile_identity_suci, scheme_output[i]);
ogs_assert(test_ue[i]);
test_ue[i]->nr_cgi.cell_id = 0x40001;
test_ue[i]->nas.registration.tsc = 0;
test_ue[i]->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
test_ue[i]->nas.registration.follow_on_request = 1;
test_ue[i]->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
test_ue[i]->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
test_ue[i]->opc_string = "e8ed289deba952e4283b54e88e6183ca";
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
if (i > 0)
test_ue[i]->ran_ue_ngap_id = test_ue[i-1]->ran_ue_ngap_id;
else
test_ue[i]->ran_ue_ngap_id = 0;
/* pdu_id == 5 */
/* Send PDU session establishment request */
sess = test_sess_add_by_dnn_and_psi(test_ue[i], "internet", 5);
ogs_assert(sess);
/********** Insert Subscriber in Database */
doc = test_db_new_simple(test_ue[i]);
ABTS_PTR_NOTNULL(tc, doc);
ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue[i], doc));
/* Send Registration request - with SUCI */
// test_ue[i]->registration_request_param.guti = 1;
gmmbuf = testgmm_build_registration_request(test_ue[i], NULL, false, false);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue[i]->registration_request_param.gmm_capability = 1;
test_ue[i]->registration_request_param.s1_ue_network_capability = 1;
test_ue[i]->registration_request_param.requested_nssai = 1;
test_ue[i]->registration_request_param.last_visited_registered_tai = 1;
test_ue[i]->registration_request_param.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(test_ue[i], NULL, false, false);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(test_ue[i], gmmbuf,
NGAP_RRCEstablishmentCause_mo_Signalling, false, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
#if 0
/* Receive Identity request */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
/* Send Identity response */
gmmbuf = testgmm_build_identity_response(test_ue[i]);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
#endif
/* Receive Authentication request */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
/* Send Authentication response */
gmmbuf = testgmm_build_authentication_response(test_ue[i]);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode command */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
/* Send Security mode complete */
gmmbuf = testgmm_build_security_mode_complete(test_ue[i], nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive InitialContextSetupRequest +
* Registration accept */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_InitialContextSetup,
test_ue[i]->ngap_procedure_code);
/* Send UERadioCapabilityInfoIndication */
sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue[i]);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send InitialContextSetupResponse */
sendbuf = testngap_build_initial_context_setup_response(test_ue[i], false);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue[i]);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
sess->ul_nas_transport_param.request_type =
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;
sess->ul_nas_transport_param.dnn = 1;
sess->ul_nas_transport_param.s_nssai = 0;
sess->pdu_session_establishment_param.ssc_mode = 1;
sess->pdu_session_establishment_param.epco = 1;
gsmbuf = testgsm_build_pdu_session_establishment_request(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDUSessionResourceSetupRequest +
* DL NAS transport +
* PDU session establishment accept */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_PDUSessionResourceSetup,
test_ue[i]->ngap_procedure_code);
/* Send PDUSessionResourceSetupResponse */
sendbuf = testngap_sess_build_pdu_session_resource_setup_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
/* Send PDU session release request */
sess = test_sess_find_by_psi(test_ue[i], 5);
ogs_assert(sess);
/* Send PDU Session release request */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;
sess->pdu_session_establishment_param.ssc_mode = 0;
sess->pdu_session_establishment_param.epco = 0;
gsmbuf = testgsm_build_pdu_session_release_request(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDUSessionResourceReleaseCommand +
* DL NAS transport +
* PDU session release command */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_PDUSessionResourceRelease,
test_ue[i]->ngap_procedure_code);
/* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send UplinkNASTransport +
* UL NAS trasnport +
* PDU session resource release complete */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;
sess->pdu_session_establishment_param.ssc_mode = 0;
sess->pdu_session_establishment_param.epco = 0;
gsmbuf = testgsm_build_pdu_session_release_complete(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
/* Send De-registration request */
gmmbuf = testgmm_build_de_registration_request(test_ue[i], 1, true, true);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UEContextReleaseCommand */
recvbuf = testgnb_ngap_read(ngap1);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue[i], recvbuf);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_UEContextRelease,
test_ue[i]->ngap_procedure_code);
/* Send UEContextReleaseComplete */
sendbuf = testngap_build_ue_context_release_complete(test_ue[i]);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap1, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
/*
* Terminate Old AMF to simulate any kind of situation, where UE
* registers with GUTI from Old AMF which is not present anymore.
* Registration must not be rejected and must continue with
* identity request
*/
test_child_terminate_with_name("amf", 0);
ogs_msleep(300);
/* Register to Target AMF */
/* Make the same UE from scratch and give it the 5G GUTI from Old AMF */
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
const char *scheme_output_target[] = {
"0000000001",
"0000000002",
"0000000003",
"0000000004",
"0000000005",
};
/* 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_target[i] = test_ue_add_by_suci(
&mobile_identity_suci, scheme_output_target[i]);
ogs_assert(test_ue_target[i]);
test_ue_target[i]->nr_cgi.cell_id = 0x40000;
test_ue_target[i]->nas.registration.tsc = 0;
test_ue_target[i]->nas.registration.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
test_ue_target[i]->nas.registration.follow_on_request = 1;
test_ue_target[i]->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
test_ue_target[i]->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc";
test_ue_target[i]->opc_string = "e8ed289deba952e4283b54e88e6183ca";
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
if (i > 0)
test_ue_target[i]->ran_ue_ngap_id = test_ue_target[i-1]->ran_ue_ngap_id;
else
test_ue_target[i]->ran_ue_ngap_id = 0;
/* pdu_id == 6 */
/* Send PDU session establishment request */
sess = test_sess_add_by_dnn_and_psi(test_ue_target[i], "internet", 6);
ogs_assert(sess);
/********** Insert Subscriber in Database */
doc = test_db_new_simple(test_ue_target[i]);
ABTS_PTR_NOTNULL(tc, doc);
ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue_target[i], doc));
/* Set the 5G GUTI to Old AMF's 5G GUTI */
test_ue_target[i]->nas_5gs_guti = test_ue[i]->nas_5gs_guti;
/* Send Registration request */
test_ue_target[i]->registration_request_param.guti = 1;
gmmbuf = testgmm_build_registration_request(test_ue_target[i], NULL, false, false);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue_target[i]->registration_request_param.gmm_capability = 1;
test_ue_target[i]->registration_request_param.s1_ue_network_capability = 1;
test_ue_target[i]->registration_request_param.requested_nssai = 1;
test_ue_target[i]->registration_request_param.last_visited_registered_tai = 1;
test_ue_target[i]->registration_request_param.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(test_ue_target[i], NULL, false, false);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(test_ue_target[i], gmmbuf,
NGAP_RRCEstablishmentCause_mo_Signalling, false, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Identity request */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
/* Send Identity response */
gmmbuf = testgmm_build_identity_response(test_ue_target[i]);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Authentication request */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
/* Send Authentication response */
gmmbuf = testgmm_build_authentication_response(test_ue_target[i]);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode command */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
/* Send Security mode complete */
gmmbuf = testgmm_build_security_mode_complete(test_ue_target[i], nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive InitialContextSetupRequest +
* Registration accept */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_InitialContextSetup,
test_ue_target[i]->ngap_procedure_code);
/* Send UERadioCapabilityInfoIndication */
sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue_target[i]);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send InitialContextSetupResponse */
sendbuf = testngap_build_initial_context_setup_response(test_ue_target[i], false);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue_target[i]);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
sess->ul_nas_transport_param.request_type =
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;
sess->ul_nas_transport_param.dnn = 1;
sess->ul_nas_transport_param.s_nssai = 0;
sess->pdu_session_establishment_param.ssc_mode = 1;
sess->pdu_session_establishment_param.epco = 1;
gsmbuf = testgsm_build_pdu_session_establishment_request(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDUSessionResourceSetupRequest +
* DL NAS transport +
* PDU session establishment accept */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_PDUSessionResourceSetup,
test_ue_target[i]->ngap_procedure_code);
/* Send PDUSessionResourceSetupResponse */
sendbuf = testngap_sess_build_pdu_session_resource_setup_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
/* Send PDU session release request */
sess = test_sess_find_by_psi(test_ue_target[i], 6);
ogs_assert(sess);
/* Send PDU Session release request */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;
sess->pdu_session_establishment_param.ssc_mode = 0;
sess->pdu_session_establishment_param.epco = 0;
gsmbuf = testgsm_build_pdu_session_release_request(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDUSessionResourceReleaseCommand +
* DL NAS transport +
* PDU session release command */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_PDUSessionResourceRelease,
test_ue_target[i]->ngap_procedure_code);
/* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send UplinkNASTransport +
* UL NAS trasnport +
* PDU session resource release complete */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;
sess->pdu_session_establishment_param.ssc_mode = 0;
sess->pdu_session_establishment_param.epco = 0;
gsmbuf = testgsm_build_pdu_session_release_complete(sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
/* Send De-registration request */
gmmbuf = testgmm_build_de_registration_request(test_ue_target[i], 1, true, true);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue_target[i], gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UEContextReleaseCommand */
recvbuf_target = testgnb_ngap_read(ngap2);
ABTS_PTR_NOTNULL(tc, recvbuf_target);
testngap_recv(test_ue_target[i], recvbuf_target);
ABTS_INT_EQUAL(tc,
NGAP_ProcedureCode_id_UEContextRelease,
test_ue_target[i]->ngap_procedure_code);
/* Send UEContextReleaseComplete */
sendbuf = testngap_build_ue_context_release_complete(test_ue_target[i]);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap2, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
}
ogs_msleep(300);
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
/********** Remove Subscriber in Database */
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue_target[i]));
}
for (i = 0; i < NUM_OF_TEST_UE_1; i++) {
/********** Remove Subscriber in Database */
ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue[i]));
}
/* Clear Test UE Context */
test_ue_remove_all();
/* gNB disonncect from UPF */
testgnb_gtpu_close(gtpu2);
/* gNB disonncect from UPF */
testgnb_gtpu_close(gtpu1);
/* gNB disonncect from Target AMF */
testgnb_ngap_close(ngap2);
/* gNB disonncect from Old AMF */
testgnb_ngap_close(ngap1);
}
abts_suite *test_ue_context_transfer_error_case(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func_error, NULL);
return suite;
}