[SMF] Added SMF registrations (#2514, #2524)

This commit is contained in:
Sukchan Lee 2023-08-18 20:14:33 +09:00
parent e01f46eb6c
commit fc4072590e
31 changed files with 1329 additions and 230 deletions

View File

@ -107,6 +107,8 @@ void ogs_sbi_message_free(ogs_sbi_message_t *message)
if (message->Amf3GppAccessRegistrationModification)
OpenAPI_amf3_gpp_access_registration_modification_free(
message->Amf3GppAccessRegistrationModification);
if (message->SmfRegistration)
OpenAPI_smf_registration_free(message->SmfRegistration);
if (message->AccessAndMobilitySubscriptionData)
OpenAPI_access_and_mobility_subscription_data_free(
message->AccessAndMobilitySubscriptionData);
@ -1053,6 +1055,9 @@ static char *build_json(ogs_sbi_message_t *message)
item = OpenAPI_amf3_gpp_access_registration_modification_convertToJSON(
message->Amf3GppAccessRegistrationModification);
ogs_assert(item);
} else if (message->SmfRegistration) {
item = OpenAPI_smf_registration_convertToJSON(message->SmfRegistration);
ogs_assert(item);
} else if (message->AccessAndMobilitySubscriptionData) {
item = OpenAPI_access_and_mobility_subscription_data_convertToJSON(
message->AccessAndMobilitySubscriptionData);
@ -1357,8 +1362,6 @@ static int parse_json(ogs_sbi_message_t *message,
}
}
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Unknown method [%s]", message->h.method);
@ -1426,7 +1429,6 @@ static int parse_json(ogs_sbi_message_t *message,
CASE(OGS_SBI_RESOURCE_NAME_REGISTRATIONS)
SWITCH(message->h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_AMF_3GPP_ACCESS)
SWITCH(message->h.method)
CASE(OGS_SBI_HTTP_METHOD_PUT)
if (message->res_status < 300) {
@ -1461,6 +1463,21 @@ static int parse_json(ogs_sbi_message_t *message,
ogs_error("Unknown method [%s]", message->h.method);
END
break;
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
if (message->res_status < 300) {
message->SmfRegistration =
OpenAPI_smf_registration_parseFromJSON(item);
if (!message->SmfRegistration) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
} else {
ogs_error("HTTP ERROR Status : %d",
message->res_status);
}
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Unknown resource name [%s]",
@ -1599,18 +1616,39 @@ static int parse_json(ogs_sbi_message_t *message,
break;
CASE(OGS_SBI_RESOURCE_NAME_CONTEXT_DATA)
if (message->res_status < 300) {
message->Amf3GppAccessRegistration =
OpenAPI_amf3_gpp_access_registration_parseFromJSON(
item);
if (!message->Amf3GppAccessRegistration) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
SWITCH(message->h.resource.component[3])
CASE(OGS_SBI_RESOURCE_NAME_AMF_3GPP_ACCESS)
if (message->res_status < 300) {
message->Amf3GppAccessRegistration =
OpenAPI_amf3_gpp_access_registration_parseFromJSON(
item);
if (!message->Amf3GppAccessRegistration) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
} else {
ogs_error("HTTP ERROR Status : %d",
message->res_status);
}
} else {
ogs_error("HTTP ERROR Status : %d",
message->res_status);
}
break;
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
if (message->res_status < 300) {
message->SmfRegistration =
OpenAPI_smf_registration_parseFromJSON(item);
if (!message->SmfRegistration) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
} else {
ogs_error("HTTP ERROR Status : %d",
message->res_status);
}
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Unknown resource name [%s]",
message->h.resource.component[3]);
END
break;
DEFAULT
@ -1897,33 +1935,22 @@ static int parse_json(ogs_sbi_message_t *message,
CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_POLICIES)
SWITCH(message->h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
if (message->res_status == 0) {
message->PolicyAssociationRequest =
OpenAPI_policy_association_request_parseFromJSON(
item);
if (!message->PolicyAssociationRequest) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
} else if (message->res_status ==
OGS_SBI_HTTP_STATUS_CREATED) {
message->PolicyAssociation =
OpenAPI_policy_association_parseFromJSON(item);
if (!message->PolicyAssociation) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
if (message->res_status == 0) {
message->PolicyAssociationRequest =
OpenAPI_policy_association_request_parseFromJSON(item);
if (!message->PolicyAssociationRequest) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
/* Nothing */
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Unknown method [%s]", message->h.method);
END
} else if (message->res_status ==
OGS_SBI_HTTP_STATUS_CREATED) {
message->PolicyAssociation =
OpenAPI_policy_association_parseFromJSON(item);
if (!message->PolicyAssociation) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
}
break;
DEFAULT
rv = OGS_ERROR;
@ -2005,23 +2032,14 @@ static int parse_json(ogs_sbi_message_t *message,
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_PCF_BINDINGS)
if (message->h.resource.component[1]) {
SWITCH(message->h.method)
CASE(OGS_SBI_HTTP_METHOD_PATCH)
if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
message->PcfBinding =
OpenAPI_pcf_binding_parseFromJSON(item);
if (!message->PcfBinding) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
message->PcfBinding =
OpenAPI_pcf_binding_parseFromJSON(item);
if (!message->PcfBinding) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Unknown method [%s]", message->h.method);
END
}
break;
} else {
SWITCH(message->h.method)

View File

@ -102,6 +102,7 @@ extern "C" {
#define OGS_SBI_RESOURCE_NAME_AUTH_EVENTS "auth-events"
#define OGS_SBI_RESOURCE_NAME_REGISTRATIONS "registrations"
#define OGS_SBI_RESOURCE_NAME_AMF_3GPP_ACCESS "amf-3gpp-access"
#define OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS "smf-registrations"
#define OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA "subscription-data"
#define OGS_SBI_RESOURCE_NAME_AUTHENTICATION_DATA "authentication-data"
@ -509,6 +510,7 @@ typedef struct ogs_sbi_message_s {
OpenAPI_deregistration_data_t *DeregistrationData;
OpenAPI_sdm_subscription_t *SDMSubscription;
OpenAPI_modification_notification_t *ModificationNotification;
OpenAPI_smf_registration_t *SmfRegistration;
ogs_sbi_links_t *links;

View File

@ -592,7 +592,13 @@ static bool server_send_rspmem_persistent(
i = 0;
ogs_assert(strlen(status_string[response->status]) == 3);
if (strlen(status_string[response->status]) != 3) {
ogs_fatal("response status [%d]", response->status);
ogs_fatal("status string [%s]", status_string[response->status]);
ogs_assert_if_reached();
return false;
}
add_header(&nva[i++], ":status", status_string[response->status]);
ogs_snprintf(srv_version, sizeof(srv_version),

View File

@ -46,6 +46,7 @@
#include "model/auth_event.h"
#include "model/amf3_gpp_access_registration.h"
#include "model/amf3_gpp_access_registration_modification.h"
#include "model/smf_registration.h"
#include "model/access_and_mobility_subscription_data.h"
#include "model/smf_selection_subscription_data.h"
#include "model/ue_context_in_smf_data.h"

View File

@ -380,6 +380,11 @@ typedef struct smf_sess_s {
int pdu_session_resource_release;
} ngap_state;
#define SMF_UECM_STATE_NONE 0
#define SMF_UECM_STATE_REGISTERED 1
#define SMF_UECM_STATE_DEREGISTERED_BY_AMF 2
#define SMF_UECM_STATE_DEREGISTERED_BY_N1_N2_RELEASE 3
/* Handover */
struct {
bool prepared;

View File

@ -154,63 +154,6 @@ static bool send_ccr_termination_req_gx_gy_s6b(smf_sess_t *sess, smf_event_t *e)
return true;
}
static bool send_sbi_message_from_delete_trigger(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger)
{
ogs_sbi_message_t sendmsg;
ogs_sbi_response_t *response = NULL;
if (trigger == OGS_PFCP_DELETE_TRIGGER_LOCAL_INITIATED) {
/* Nothing */
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
n1smbuf = gsm_build_pdu_session_release_command(
sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(n2smbuf);
ogs_assert(stream);
smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD, n2smbuf);
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
trigger == OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
memset(&sendmsg, 0, sizeof(sendmsg));
response = ogs_sbi_build_response(
&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
ogs_assert(stream);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_PDU_SESSION_RELEASE;
param.n2smbuf =
ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
param.skip_ind = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
ogs_fatal("Unknown trigger [%d]", trigger);
ogs_assert_if_reached();
}
return true;
}
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
int rv;
@ -449,7 +392,7 @@ test_can_proceed:
diam_err = sess->sm_data.gy_cca_init_err;
if (diam_err == ER_DIAMETER_SUCCESS) {
OGS_FSM_TRAN(s, &smf_gsm_state_wait_pfcp_establishment);
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_establishment);
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_establishment_request(
sess, e->gtp_xact, 0));
@ -673,7 +616,7 @@ void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
/* If no CreatePDPCtxResp can be sent,
* then tear down the session: */
if (rv != OGS_OK) {
OGS_FSM_TRAN(s, &smf_gsm_state_wait_pfcp_deletion);
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
return;
}
}
@ -713,7 +656,7 @@ void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
}
OGS_FSM_TRAN(s, &smf_gsm_state_operational);
OGS_FSM_TRAN(s, smf_gsm_state_operational);
break;
default:
@ -794,7 +737,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, gtp1_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_wait_pfcp_deletion);
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
}
break;
@ -812,14 +755,14 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp2_cause);
return;
}
OGS_FSM_TRAN(s, &smf_gsm_state_wait_pfcp_deletion);
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
break;
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
release = smf_s5c_handle_delete_bearer_response(
sess, e->gtp_xact, &e->gtp2_message->delete_bearer_response);
if (release) {
e->gtp_xact = NULL;
OGS_FSM_TRAN(s, &smf_gsm_state_wait_pfcp_deletion);
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
}
break;
@ -855,8 +798,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
break;
case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE:
ogs_error("Session Released by Error Indication");
OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
ogs_error("EPC Session Released by Error Indication");
OGS_FSM_TRAN(s, smf_gsm_state_epc_session_will_release);
break;
default:
@ -1320,7 +1263,7 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
}
e->gtp_xact = gtp_xact;
if (send_ccr_termination_req_gx_gy_s6b(sess, e) == true)
OGS_FSM_TRAN(s, &smf_gsm_state_wait_epc_auth_release);
OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_release);
/* else: free session? */
} else {
int trigger;
@ -1339,35 +1282,67 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
"[%d] smf_5gc_n4_handle_session_deletion_response() "
"failed", trigger);
OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
OGS_FSM_TRAN(s, smf_gsm_state_5gc_session_will_deregister);
break;
}
if (send_sbi_message_from_delete_trigger(
sess, stream, trigger) == true) {
if (trigger == OGS_PFCP_DELETE_TRIGGER_LOCAL_INITIATED) {
if (trigger == OGS_PFCP_DELETE_TRIGGER_LOCAL_INITIATED) {
ogs_error("OLD Session Released");
OGS_FSM_TRAN(s, smf_gsm_state_5gc_session_will_deregister);
ogs_warn("OLD Session Released");
OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
} else if (
trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED ||
trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
n1smbuf = gsm_build_pdu_session_release_command(
sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
ogs_assert(n1smbuf);
OGS_FSM_TRAN(s, smf_gsm_state_wait_5gc_n1_n2_release);
n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(n2smbuf);
} else if (trigger ==
ogs_assert(stream);
smf_sbi_send_sm_context_updated_data_n1_n2_message(
sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD,
n2smbuf);
OGS_FSM_TRAN(s, smf_gsm_state_wait_5gc_n1_n2_release);
} else if (trigger ==
OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
trigger ==
trigger ==
OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
int r = smf_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_UECM, NULL,
smf_nudm_uecm_build_deregistration, sess, stream,
SMF_UECM_STATE_DEREGISTERED_BY_AMF, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
} else {
ogs_fatal("Unknown trigger [%d]", trigger);
ogs_assert_if_reached();
}
OGS_FSM_TRAN(s, smf_gsm_state_5gc_session_will_deregister);
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_PDU_SESSION_RELEASE;
param.n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
param.skip_ind = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
OGS_FSM_TRAN(s, smf_gsm_state_wait_5gc_n1_n2_release);
} else {
ogs_fatal("Unknown trigger [%d]", trigger);
ogs_assert_if_reached();
}
}
break;
@ -1497,7 +1472,7 @@ test_can_proceed:
send_gtp_delete_err_msg(sess, e->gtp_xact, gtp_cause);
}
}
OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release);
OGS_FSM_TRAN(s, smf_gsm_state_epc_session_will_release);
}
}
@ -1576,6 +1551,9 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
ogs_warn("[%s:%d] state [%d] res_status [%d]",
smf_ue->supi, sess->psi,
e->h.sbi.state, sbi_message->res_status);
smf_namf_comm_handle_n1_n2_message_transfer(
sess, e->h.sbi.state, sbi_message);
break;
@ -1648,7 +1626,14 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e)
sess->n2_released = true;
if ((sess->n1_released) && (sess->n2_released)) {
OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release);
int r = smf_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_UECM, NULL,
smf_nudm_uecm_build_deregistration, sess, NULL,
SMF_UECM_STATE_DEREGISTERED_BY_N1_N2_RELEASE, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, smf_gsm_state_5gc_session_will_deregister);
}
} else {
@ -1674,11 +1659,17 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e)
switch (nas_message->gsm.h.message_type) {
case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE:
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
ogs_assert(true == smf_sbi_send_sm_context_status_notify(sess));
sess->n1_released = true;
if ((sess->n1_released) && (sess->n2_released)) {
OGS_FSM_TRAN(s, &smf_gsm_state_session_will_release);
int r = smf_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_UECM, NULL,
smf_nudm_uecm_build_deregistration, sess, NULL,
SMF_UECM_STATE_DEREGISTERED_BY_N1_N2_RELEASE, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
OGS_FSM_TRAN(s, smf_gsm_state_5gc_session_will_deregister);
}
break;
@ -1793,7 +1784,7 @@ void smf_gsm_state_5gc_n1_n2_reject(ogs_fsm_t *s, smf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
OGS_FSM_TRAN(s, smf_gsm_state_session_will_release);
OGS_FSM_TRAN(s, smf_gsm_state_epc_session_will_release);
break;
DEFAULT
@ -1817,7 +1808,27 @@ void smf_gsm_state_5gc_n1_n2_reject(ogs_fsm_t *s, smf_event_t *e)
}
}
void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e)
void smf_gsm_state_5gc_session_will_deregister(ogs_fsm_t *s, smf_event_t *e)
{
ogs_assert(s);
ogs_assert(e);
smf_sm_debug(e);
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
default:
ogs_error("Unknown event %s", smf_event_get_name(e));
break;
}
}
void smf_gsm_state_epc_session_will_release(ogs_fsm_t *s, smf_event_t *e)
{
smf_sess_t *sess = NULL;
ogs_assert(s);

View File

@ -401,7 +401,12 @@ void smf_5gc_n4_handle_session_modification_response(
smf_sbi_send_sm_context_updated_data_up_cnx_state(
sess, stream, OpenAPI_up_cnx_state_ACTIVATED);
} else {
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
int r = smf_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDM_UECM, NULL,
smf_nudm_uecm_build_registration,
sess, stream, SMF_UECM_STATE_REGISTERED, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
}
}

View File

@ -49,3 +49,105 @@ ogs_sbi_request_t *smf_nudm_sdm_build_get(smf_sess_t *sess, void *data)
return request;
}
ogs_sbi_request_t *smf_nudm_uecm_build_registration(
smf_sess_t *sess, void *data)
{
smf_ue_t *smf_ue = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
OpenAPI_smf_registration_t SmfRegistration;
OpenAPI_snssai_t single_nssai;
ogs_assert(sess);
ogs_assert(sess->psi);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
ogs_assert(smf_ue->supi);
memset(&message, 0, sizeof(message));
memset(&SmfRegistration, 0, sizeof(SmfRegistration));
message.SmfRegistration = &SmfRegistration;
memset(&single_nssai, 0, sizeof(single_nssai));
SmfRegistration.single_nssai = &single_nssai;
message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NUDM_UECM;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] = smf_ue->supi;
message.h.resource.component[1] =
(char *)OGS_SBI_RESOURCE_NAME_REGISTRATIONS;
message.h.resource.component[2] =
(char *)OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS;
message.h.resource.component[3] = ogs_msprintf("%d", sess->psi);
if (!message.h.resource.component[3]) {
ogs_error("No memory : message.h.resource.component[3]");
goto end;
}
SmfRegistration.smf_instance_id =
NF_INSTANCE_ID(ogs_sbi_self()->nf_instance);
SmfRegistration.pdu_session_id = sess->psi;
single_nssai.sst = sess->s_nssai.sst;
single_nssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
SmfRegistration.dnn = sess->session.name;
SmfRegistration.plmn_id = ogs_sbi_build_plmn_id(&sess->plmn_id);
if (!SmfRegistration.plmn_id) {
ogs_error("No memory : SmfRegistration.plmn_id");
goto end;
}
request = ogs_sbi_build_request(&message);
ogs_expect(request);
end:
ogs_free(message.h.resource.component[3]);
ogs_free(single_nssai.sd);
ogs_sbi_free_plmn_id(SmfRegistration.plmn_id);
return request;
}
ogs_sbi_request_t *smf_nudm_uecm_build_deregistration(
smf_sess_t *sess, void *data)
{
smf_ue_t *smf_ue = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
ogs_assert(sess);
ogs_assert(sess->psi);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
ogs_assert(smf_ue->supi);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_DELETE;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NUDM_UECM;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] = smf_ue->supi;
message.h.resource.component[1] =
(char *)OGS_SBI_RESOURCE_NAME_REGISTRATIONS;
message.h.resource.component[2] =
(char *)OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS;
message.h.resource.component[3] = ogs_msprintf("%d", sess->psi);
if (!message.h.resource.component[3]) {
ogs_error("No memory : message.h.resource.component[3]");
goto end;
}
request = ogs_sbi_build_request(&message);
ogs_expect(request);
end:
ogs_free(message.h.resource.component[3]);
return request;
}

View File

@ -28,6 +28,11 @@ extern "C" {
ogs_sbi_request_t *smf_nudm_sdm_build_get(smf_sess_t *sess, void *data);
ogs_sbi_request_t *smf_nudm_uecm_build_registration(
smf_sess_t *sess, void *data);
ogs_sbi_request_t *smf_nudm_uecm_build_deregistration(
smf_sess_t *sess, void *data);
#ifdef __cplusplus
}
#endif

View File

@ -67,6 +67,8 @@ int smf_sbi_open(void)
OpenAPI_nf_type_PCF, OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL);
ogs_sbi_subscription_spec_add(
OpenAPI_nf_type_UDM, OGS_SBI_SERVICE_NAME_NUDM_SDM);
ogs_sbi_subscription_spec_add(
OpenAPI_nf_type_UDM, OGS_SBI_SERVICE_NAME_NUDM_UECM);
if (ogs_sbi_server_start_all(ogs_sbi_server_handler) != OGS_OK)
return OGS_ERROR;
@ -109,10 +111,11 @@ int smf_sbi_discover_and_send(
(ogs_sbi_build_f)build, sess, data);
if (!xact) {
ogs_error("smf_sbi_discover_and_send() failed");
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", smf_ue->supi));
if (stream)
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", smf_ue->supi));
return OGS_ERROR;
}

View File

@ -791,9 +791,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_error("Session has already been removed");
break;
}
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
smf_ue = smf_ue_cycle(smf_ue);
smf_ue = smf_ue_cycle(sess->smf_ue);
ogs_assert(smf_ue);
ogs_assert(OGS_FSM_STATE(&sess->sm));
@ -803,6 +801,88 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_fsm_dispatch(&sess->sm, e);
break;
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
int state = 0;
bool unknown_res_status = false;
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
if (!sbi_xact) {
/* CLIENT_WAIT timer could remove SBI transaction
* before receiving SBI message */
ogs_error("SBI transaction has already been removed");
break;
}
sess = (smf_sess_t *)sbi_xact->sbi_object;
ogs_assert(sess);
stream = sbi_xact->assoc_stream;
state = sbi_xact->state;
ogs_assert(state);
ogs_sbi_xact_remove(sbi_xact);
sess = smf_sess_cycle(sess);
if (!sess) {
ogs_error("Session has already been removed");
break;
}
smf_ue = smf_ue_cycle(sess->smf_ue);
ogs_assert(smf_ue);
if (state == SMF_UECM_STATE_REGISTERED) {
/* SMF Registration */
if (sbi_message.res_status != OGS_SBI_HTTP_STATUS_OK &&
sbi_message.res_status != OGS_SBI_HTTP_STATUS_CREATED)
unknown_res_status = true;
} else if (state == SMF_UECM_STATE_DEREGISTERED_BY_AMF ||
state == SMF_UECM_STATE_DEREGISTERED_BY_N1_N2_RELEASE) {
/* SMF Deregistration */
if (sbi_message.res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT)
unknown_res_status = true;
} else {
ogs_fatal("Unknown state [%d]", state);
ogs_assert_if_reached();
}
if (unknown_res_status == true) {
char *strerror = ogs_msprintf(
"[%s:%d] HTTP response error [%d] state [%d]",
smf_ue->supi, sess->psi, sbi_message.res_status, state);
ogs_assert(strerror);
ogs_error("%s", strerror);
if (stream)
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
NULL, strerror, NULL));
ogs_free(strerror);
OGS_FSM_TRAN(s, smf_gsm_state_exception);
break;
}
if (state == SMF_UECM_STATE_REGISTERED) {
/* SMF Registration */
ogs_assert(stream);
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
} else if (state == SMF_UECM_STATE_DEREGISTERED_BY_AMF) {
/* SMF Deregistration */
ogs_assert(stream);
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
SMF_SESS_CLEAR(sess);
} else if (state == SMF_UECM_STATE_DEREGISTERED_BY_N1_N2_RELEASE) {
/* SMF Deregistration */
ogs_assert(true == smf_sbi_send_sm_context_status_notify(sess));
SMF_SESS_CLEAR(sess);
}
break;
DEFAULT
ogs_error("Invalid service name [%s]", sbi_message.h.service.name);
ogs_assert_if_reached();

View File

@ -41,7 +41,8 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_wait_epc_auth_release(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_5gc_n1_n2_reject(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_session_will_release(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_5gc_session_will_deregister(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_epc_session_will_release(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e);
void smf_pfcp_state_initial(ogs_fsm_t *s, smf_event_t *e);

View File

@ -24,6 +24,7 @@ static udm_context_t self;
int __udm_log_domain;
static OGS_POOL(udm_ue_pool, udm_ue_t);
static OGS_POOL(udm_sess_pool, udm_sess_t);
static int context_initialized = 0;
@ -37,6 +38,7 @@ void udm_context_init(void)
ogs_log_install_domain(&__udm_log_domain, "udm", ogs_core()->log.level);
ogs_pool_init(&udm_ue_pool, ogs_app()->max.ue);
ogs_pool_init(&udm_sess_pool, ogs_app()->pool.sess);
ogs_list_init(&self.udm_ue_list);
self.suci_hash = ogs_hash_make();
@ -59,6 +61,7 @@ void udm_context_final(void)
ogs_hash_destroy(self.supi_hash);
ogs_pool_final(&udm_ue_pool);
ogs_pool_final(&udm_sess_pool);
context_initialized = 0;
}
@ -132,6 +135,9 @@ udm_ue_t *udm_ue_add(char *suci)
ogs_assert(udm_ue);
memset(udm_ue, 0, sizeof *udm_ue);
/* SBI Type */
udm_ue->sbi.type = OGS_SBI_OBJ_UE_TYPE;
udm_ue->ctx_id = ogs_msprintf("%d",
(int)ogs_pool_index(&udm_ue_pool, udm_ue));
ogs_assert(udm_ue->ctx_id);
@ -168,6 +174,8 @@ void udm_ue_remove(udm_ue_t *udm_ue)
/* Free SBI object memory */
ogs_sbi_object_free(&udm_ue->sbi);
udm_sess_remove_all(udm_ue);
OpenAPI_auth_event_free(udm_ue->auth_event);
OpenAPI_amf3_gpp_access_registration_free(
udm_ue->amf_3gpp_access_registration);
@ -232,11 +240,90 @@ udm_ue_t *udm_ue_find_by_ctx_id(char *ctx_id)
return ogs_pool_find(&udm_ue_pool, atoll(ctx_id));
}
udm_sess_t *udm_sess_add(udm_ue_t *udm_ue, uint8_t psi)
{
udm_event_t e;
udm_sess_t *sess = NULL;
ogs_assert(udm_ue);
ogs_assert(psi != OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED);
ogs_pool_alloc(&udm_sess_pool, &sess);
ogs_assert(sess);
memset(sess, 0, sizeof *sess);
/* SBI Type */
sess->sbi.type = OGS_SBI_OBJ_SESS_TYPE;
sess->udm_ue = udm_ue;
sess->psi = psi;
memset(&e, 0, sizeof(e));
e.sess = sess;
ogs_fsm_init(&sess->sm, udm_sess_state_initial, udm_sess_state_final, &e);
ogs_list_add(&udm_ue->sess_list, sess);
return sess;
}
void udm_sess_remove(udm_sess_t *sess)
{
udm_event_t e;
ogs_assert(sess);
ogs_assert(sess->udm_ue);
ogs_list_remove(&sess->udm_ue->sess_list, sess);
memset(&e, 0, sizeof(e));
e.sess = sess;
ogs_fsm_fini(&sess->sm, &e);
/* Free SBI object memory */
if (ogs_list_count(&sess->sbi.xact_list))
ogs_error("Session transaction [%d]",
ogs_list_count(&sess->sbi.xact_list));
ogs_sbi_object_free(&sess->sbi);
OpenAPI_smf_registration_free(sess->smf_registration);
if (sess->smf_instance_id)
ogs_free(sess->smf_instance_id);
ogs_pool_free(&udm_sess_pool, sess);
}
void udm_sess_remove_all(udm_ue_t *udm_ue)
{
udm_sess_t *sess = NULL, *next_sess = NULL;
ogs_assert(udm_ue);
ogs_list_for_each_safe(&udm_ue->sess_list, next_sess, sess)
udm_sess_remove(sess);
}
udm_sess_t *udm_sess_find_by_psi(udm_ue_t *udm_ue, uint8_t psi)
{
udm_sess_t *sess = NULL;
ogs_list_for_each(&udm_ue->sess_list, sess)
if (psi == sess->psi) return sess;
return NULL;
}
udm_ue_t *udm_ue_cycle(udm_ue_t *udm_ue)
{
return ogs_pool_cycle(&udm_ue_pool, udm_ue);
}
udm_sess_t *udm_sess_cycle(udm_sess_t *sess)
{
return ogs_pool_cycle(&udm_sess_pool, sess);
}
int get_ue_load(void)
{
return (((ogs_pool_size(&udm_ue_pool) -

View File

@ -70,6 +70,22 @@ struct udm_ue_s {
OpenAPI_auth_type_e auth_type;
OpenAPI_rat_type_e rat_type;
ogs_list_t sess_list;
};
struct udm_sess_s {
ogs_sbi_object_t sbi;
ogs_fsm_t sm;
uint8_t psi; /* PDU Session Identity */
OpenAPI_smf_registration_t *smf_registration;
char *smf_instance_id;
/* Related Context */
udm_ue_t *udm_ue;
};
void udm_context_init(void);
@ -86,7 +102,14 @@ udm_ue_t *udm_ue_find_by_supi(char *supi);
udm_ue_t *udm_ue_find_by_suci_or_supi(char *suci_or_supi);
udm_ue_t *udm_ue_find_by_ctx_id(char *ctx_id);
udm_sess_t *udm_sess_add(udm_ue_t *udm_ue, uint8_t psi);
void udm_sess_remove(udm_sess_t *sess);
void udm_sess_remove_all(udm_ue_t *udm_ue);
udm_sess_t *udm_sess_find_by_psi(udm_ue_t *udm_ue, uint8_t psi);
udm_ue_t *udm_ue_cycle(udm_ue_t *udm_ue);
udm_sess_t *udm_sess_cycle(udm_sess_t *sess);
int get_ue_load(void);
#ifdef __cplusplus

View File

@ -27,11 +27,13 @@ extern "C" {
#endif
typedef struct udm_ue_s udm_ue_t;
typedef struct udm_sess_s udm_sess_t;
typedef struct udm_event_s {
ogs_event_t h;
udm_ue_t *udm_ue;
udm_sess_t *sess;
} udm_event_t;
OGS_STATIC_ASSERT(OGS_EVENT_SIZE >= sizeof(udm_event_t));

View File

@ -25,6 +25,7 @@ libudm_sources = files('''
nudr-build.c
nudr-handler.c
ue-sm.c
sess-sm.c
sbi-path.c
udm-sm.c

View File

@ -28,6 +28,9 @@ void udm_nnrf_handle_nf_discover(
ogs_sbi_service_type_e service_type = OGS_SBI_SERVICE_TYPE_NULL;
ogs_sbi_discovery_option_t *discovery_option = NULL;
udm_ue_t *udm_ue = NULL;
udm_sess_t *sess = NULL;
OpenAPI_nf_type_e target_nf_type = OpenAPI_nf_type_NULL;
OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
OpenAPI_search_result_t *SearchResult = NULL;
@ -51,12 +54,28 @@ void udm_nnrf_handle_nf_discover(
return;
}
if (sbi_object->type == OGS_SBI_OBJ_UE_TYPE) {
udm_ue = (udm_ue_t *)sbi_object;
ogs_assert(udm_ue);
} else if (sbi_object->type == OGS_SBI_OBJ_SESS_TYPE) {
sess = (udm_sess_t *)sbi_object;
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
} else {
ogs_fatal("(NF discover) Not implemented [%s:%d]",
ogs_sbi_service_type_to_name(service_type), sbi_object->type);
ogs_assert_if_reached();
}
ogs_nnrf_disc_handle_nf_discover_search_result(SearchResult);
nf_instance = ogs_sbi_nf_instance_find_by_discovery_param(
target_nf_type, requester_nf_type, discovery_option);
if (!nf_instance) {
ogs_error("(NF discover) No [%s:%s]",
ogs_error("[%s:%d] (NF discover) No [%s:%s]",
udm_ue ? udm_ue->supi : "Unknown",
sess ? sess->psi : 0,
ogs_sbi_service_type_to_name(service_type),
OpenAPI_nf_type_ToString(requester_nf_type));
return;

View File

@ -26,8 +26,6 @@ bool udm_nudm_ueau_handle_get(
{
OpenAPI_authentication_info_request_t *AuthenticationInfoRequest = NULL;
OpenAPI_resynchronization_info_t *ResynchronizationInfo = NULL;
char *serving_network_name = NULL;
char *ausf_instance_id = NULL;
int r;
ogs_assert(udm_ue);
@ -43,8 +41,7 @@ bool udm_nudm_ueau_handle_get(
return false;
}
serving_network_name = AuthenticationInfoRequest->serving_network_name;
if (!AuthenticationInfoRequest) {
if (!AuthenticationInfoRequest->serving_network_name) {
ogs_error("[%s] No servingNetworkName", udm_ue->suci);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
@ -52,13 +49,7 @@ bool udm_nudm_ueau_handle_get(
return false;
}
if (udm_ue->serving_network_name)
ogs_free(udm_ue->serving_network_name);
udm_ue->serving_network_name = ogs_strdup(serving_network_name);
ogs_assert(udm_ue->serving_network_name);
ausf_instance_id = AuthenticationInfoRequest->ausf_instance_id;
if (!AuthenticationInfoRequest) {
if (!AuthenticationInfoRequest->ausf_instance_id) {
ogs_error("[%s] No ausfInstanceId", udm_ue->suci);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
@ -66,15 +57,22 @@ bool udm_nudm_ueau_handle_get(
return false;
}
if (udm_ue->serving_network_name)
ogs_free(udm_ue->serving_network_name);
udm_ue->serving_network_name =
ogs_strdup(AuthenticationInfoRequest->serving_network_name);
ogs_assert(udm_ue->serving_network_name);
if (udm_ue->ausf_instance_id)
ogs_free(udm_ue->ausf_instance_id);
udm_ue->ausf_instance_id = ogs_strdup(ausf_instance_id);
udm_ue->ausf_instance_id =
ogs_strdup(AuthenticationInfoRequest->ausf_instance_id);
ogs_assert(udm_ue->ausf_instance_id);
ResynchronizationInfo = AuthenticationInfoRequest->resynchronization_info;
if (!ResynchronizationInfo) {
r = udm_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
r = udm_ue_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_authentication_subscription,
udm_ue, stream, NULL);
ogs_expect(r == OGS_OK);
@ -164,7 +162,7 @@ bool udm_nudm_ueau_handle_get(
ogs_uint64_to_buffer(sqn, OGS_SQN_LEN, udm_ue->sqn);
r = udm_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
r = udm_ue_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_authentication_subscription,
udm_ue, stream, udm_ue->sqn);
ogs_expect(r == OGS_OK);
@ -236,7 +234,7 @@ bool udm_nudm_ueau_handle_result_confirmation_inform(
udm_ue->auth_event = OpenAPI_auth_event_copy(
udm_ue->auth_event, message->AuthEvent);
r = udm_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
r = udm_ue_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_update_authentication_status,
udm_ue, stream, NULL);
ogs_expect(r == OGS_OK);
@ -245,7 +243,7 @@ bool udm_nudm_ueau_handle_result_confirmation_inform(
return true;
}
bool udm_nudm_uecm_handle_registration(
bool udm_nudm_uecm_handle_amf_registration(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message)
{
OpenAPI_amf3_gpp_access_registration_t *Amf3GppAccessRegistration = NULL;
@ -265,6 +263,14 @@ bool udm_nudm_uecm_handle_registration(
return false;
}
if (!Amf3GppAccessRegistration->amf_instance_id) {
ogs_error("[%s] No amfInstanceId", udm_ue->suci);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No amfInstanceId", udm_ue->supi));
return false;
}
if (!Amf3GppAccessRegistration->dereg_callback_uri) {
ogs_error("[%s] No dregCallbackUri", udm_ue->supi);
ogs_assert(true ==
@ -337,7 +343,7 @@ bool udm_nudm_uecm_handle_registration(
udm_ue->amf_3gpp_access_registration,
message->Amf3GppAccessRegistration);
r = udm_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
r = udm_ue_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_update_amf_context, udm_ue, stream, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
@ -345,7 +351,7 @@ bool udm_nudm_uecm_handle_registration(
return true;
}
bool udm_nudm_uecm_handle_registration_update(
bool udm_nudm_uecm_handle_amf_registration_update(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message)
{
OpenAPI_amf3_gpp_access_registration_modification_t
@ -446,7 +452,7 @@ bool udm_nudm_uecm_handle_registration_update(
OpenAPI_list_add(PatchItemList, &item);
}
r = udm_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
r = udm_ue_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_patch_amf_context,
udm_ue, stream, PatchItemList);
ogs_expect(r == OGS_OK);
@ -455,6 +461,102 @@ bool udm_nudm_uecm_handle_registration_update(
return true;
}
bool udm_nudm_uecm_handle_smf_registration(
udm_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message)
{
udm_ue_t *udm_ue = NULL;
OpenAPI_smf_registration_t *SmfRegistration = NULL;
int r;
ogs_assert(stream);
ogs_assert(message);
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
SmfRegistration = message->SmfRegistration;
if (!SmfRegistration) {
ogs_error("[%s:%d] No SmfRegistration", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No SmfRegistration", udm_ue->supi));
return false;
}
if (!SmfRegistration->smf_instance_id) {
ogs_error("[%s:%d] No smfInstanceId", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No smfInstanceId", udm_ue->supi));
return false;
}
if (!SmfRegistration->pdu_session_id) {
ogs_error("[%s:%d] No pduSessionId", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No pduSessionId", udm_ue->supi));
return false;
}
if (!SmfRegistration->single_nssai || !SmfRegistration->single_nssai->sst) {
ogs_error("[%s:%d] No singleNssai", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No singleNssai", udm_ue->supi));
return false;
}
if (!SmfRegistration->dnn) {
ogs_error("[%s:%d] No dnn", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No dnn", udm_ue->supi));
return false;
}
if (!SmfRegistration->plmn_id ||
!SmfRegistration->plmn_id->mcc || !SmfRegistration->plmn_id->mnc) {
ogs_error("[%s:%d] No plmnId", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
message, "No plmnId", udm_ue->supi));
return false;
}
sess->smf_registration =
OpenAPI_smf_registration_copy(sess->smf_registration, SmfRegistration);
r = udm_sess_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_update_smf_context, sess, stream, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
return true;
}
bool udm_nudm_uecm_handle_smf_deregistration(
udm_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message)
{
udm_ue_t *udm_ue = NULL;
int r;
ogs_assert(stream);
ogs_assert(message);
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
r = udm_sess_sbi_discover_and_send(OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_delete_smf_context, sess, stream, NULL);
ogs_expect(r == OGS_OK);
ogs_assert(r != OGS_ERROR);
return true;
}
bool udm_nudm_sdm_handle_subscription_provisioned(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{

View File

@ -31,11 +31,16 @@ bool udm_nudm_ueau_handle_get(
bool udm_nudm_ueau_handle_result_confirmation_inform(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message);
bool udm_nudm_uecm_handle_registration(
bool udm_nudm_uecm_handle_amf_registration(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message);
bool udm_nudm_uecm_handle_registration_update(
bool udm_nudm_uecm_handle_amf_registration_update(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message);
bool udm_nudm_uecm_handle_smf_registration(
udm_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message);
bool udm_nudm_uecm_handle_smf_deregistration(
udm_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message);
bool udm_nudm_sdm_handle_subscription_provisioned(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
bool udm_nudm_sdm_handle_subscription_create(

View File

@ -247,3 +247,85 @@ ogs_sbi_request_t *udm_nudr_dr_build_query_subscription_provisioned(
return request;
}
ogs_sbi_request_t *udm_nudr_dr_build_update_smf_context(
udm_sess_t *sess, void *data)
{
udm_ue_t *udm_ue = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NUDR_DR;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA;
message.h.resource.component[1] = udm_ue->supi;
message.h.resource.component[2] =
(char *)OGS_SBI_RESOURCE_NAME_CONTEXT_DATA;
message.h.resource.component[3] =
(char *)OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS;
message.h.resource.component[4] = ogs_msprintf("%d", sess->psi);
if (!message.h.resource.component[4]) {
ogs_error("No memory : message.h.resource.component[4]");
goto end;
}
message.SmfRegistration = OpenAPI_smf_registration_copy(
message.SmfRegistration, sess->smf_registration);
if (!message.SmfRegistration) {
ogs_error("OpenAPI_smf_registration_copy() failed");
goto end;
}
request = ogs_sbi_build_request(&message);
ogs_assert(request);
end:
ogs_free(message.h.resource.component[4]);
OpenAPI_smf_registration_free(message.SmfRegistration);
return request;
}
ogs_sbi_request_t *udm_nudr_dr_build_delete_smf_context(
udm_sess_t *sess, void *data)
{
udm_ue_t *udm_ue = NULL;
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_DELETE;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NUDR_DR;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA;
message.h.resource.component[1] = udm_ue->supi;
message.h.resource.component[2] =
(char *)OGS_SBI_RESOURCE_NAME_CONTEXT_DATA;
message.h.resource.component[3] =
(char *)OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS;
message.h.resource.component[4] = ogs_msprintf("%d", sess->psi);
if (!message.h.resource.component[4]) {
ogs_error("No memory : message.h.resource.component[4]");
goto end;
}
request = ogs_sbi_build_request(&message);
ogs_assert(request);
end:
ogs_free(message.h.resource.component[4]);
return request;
}

View File

@ -37,6 +37,11 @@ ogs_sbi_request_t *udm_nudr_dr_build_update_amf_context(
ogs_sbi_request_t *udm_nudr_dr_build_patch_amf_context(
udm_ue_t *udm_ue, void *data);
ogs_sbi_request_t *udm_nudr_dr_build_update_smf_context(
udm_sess_t *sess, void *data);
ogs_sbi_request_t *udm_nudr_dr_build_delete_smf_context(
udm_sess_t *sess, void *data);
#ifdef __cplusplus
}
#endif

View File

@ -396,8 +396,6 @@ bool udm_nudr_dr_handle_subscription_context(
int status;
OpenAPI_amf3_gpp_access_registration_t *Amf3GppAccessRegistration = NULL;
ogs_assert(udm_ue);
ogs_assert(stream);
server = ogs_sbi_server_from_stream(stream);
@ -441,12 +439,14 @@ bool udm_nudr_dr_handle_subscription_context(
END
END
SWITCH(recvmsg->h.resource.component[3])
CASE(OGS_SBI_RESOURCE_NAME_AMF_3GPP_ACCESS)
Amf3GppAccessRegistration = udm_ue->amf_3gpp_access_registration;
OpenAPI_amf3_gpp_access_registration_t
*Amf3GppAccessRegistration = NULL;
OpenAPI_guami_t *Guami = NULL;
Amf3GppAccessRegistration = udm_ue->amf_3gpp_access_registration;
if (!Amf3GppAccessRegistration) {
ogs_error("[%s] No Amf3GppAccessRegistration", udm_ue->supi);
ogs_assert(true ==
@ -542,10 +542,21 @@ bool udm_nudr_dr_handle_subscription_context(
if (udm_ue->amf_instance_id &&
strcmp(udm_ue->amf_instance_id,
Amf3GppAccessRegistration->amf_instance_id) == 0)
Amf3GppAccessRegistration->amf_instance_id) == 0) {
status = OGS_SBI_HTTP_STATUS_OK;
else
} else {
if (udm_ue->amf_instance_id)
ogs_free(udm_ue->amf_instance_id);
udm_ue->amf_instance_id =
ogs_strdup(Amf3GppAccessRegistration->amf_instance_id);
ogs_assert(udm_ue->amf_instance_id);
status = OGS_SBI_HTTP_STATUS_CREATED;
}
if (status == OGS_SBI_HTTP_STATUS_CREATED)
sendmsg.http.location = ogs_sbi_server_uri(server, &header);
@ -714,3 +725,175 @@ bool udm_nudr_dr_handle_subscription_provisioned(
return true;
}
bool udm_nudr_dr_handle_smf_registration(
udm_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
udm_ue_t *udm_ue = NULL;
char *strerror = NULL;
ogs_sbi_server_t *server = NULL;
ogs_sbi_message_t sendmsg;
ogs_sbi_header_t header;
ogs_sbi_response_t *response = NULL;
int status;
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
ogs_assert(stream);
server = ogs_sbi_server_from_stream(stream);
ogs_assert(server);
ogs_assert(recvmsg);
if (recvmsg->res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT) {
ogs_error("[%s:%d] HTTP response error [%d]",
udm_ue->supi, sess->psi, recvmsg->res_status);
ogs_assert(true ==
ogs_sbi_server_send_error(stream, recvmsg->res_status,
NULL, "HTTP response error", udm_ue->supi));
return false;
}
SWITCH(recvmsg->h.resource.component[3])
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
SWITCH(recvmsg->h.method)
CASE(OGS_SBI_HTTP_METHOD_PUT)
OpenAPI_smf_registration_t *SmfRegistration = NULL;
SmfRegistration = sess->smf_registration;
if (!SmfRegistration) {
ogs_error("[%s:%d] No SmfRegistration", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No SmfRegistration", udm_ue->supi));
return false;
}
if (!SmfRegistration->smf_instance_id) {
ogs_error("[%s:%d] No smfInstanceId", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No smfInstanceId", udm_ue->supi));
return false;
}
if (!SmfRegistration->pdu_session_id) {
ogs_error("[%s:%d] No pduSessionId", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No pduSessionId", udm_ue->supi));
return false;
}
if (!SmfRegistration->single_nssai ||
!SmfRegistration->single_nssai->sst) {
ogs_error("[%s:%d] No singleNssai", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No singleNssai", udm_ue->supi));
return false;
}
if (!SmfRegistration->dnn) {
ogs_error("[%s:%d] No dnn", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No dnn", udm_ue->supi));
return false;
}
if (!SmfRegistration->plmn_id ||
!SmfRegistration->plmn_id->mcc ||
!SmfRegistration->plmn_id->mnc) {
ogs_error("[%s:%d] No plmnId", udm_ue->supi, sess->psi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No plmnId", udm_ue->supi));
return false;
}
memset(&sendmsg, 0, sizeof(sendmsg));
memset(&header, 0, sizeof(header));
header.service.name = (char *)OGS_SBI_SERVICE_NAME_NUDM_UECM;
header.api.version = (char *)OGS_SBI_API_V1;
header.resource.component[0] = udm_ue->supi;
header.resource.component[1] =
(char *)OGS_SBI_RESOURCE_NAME_REGISTRATIONS;
header.resource.component[2] =
(char *)OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS;
header.resource.component[3] = ogs_msprintf("%d", sess->psi);
if (sess->smf_instance_id &&
strcmp(sess->smf_instance_id,
SmfRegistration->smf_instance_id) == 0) {
status = OGS_SBI_HTTP_STATUS_OK;
} else {
if (sess->smf_instance_id)
ogs_free(sess->smf_instance_id);
sess->smf_instance_id =
ogs_strdup(SmfRegistration->smf_instance_id);
ogs_assert(sess->smf_instance_id);
status = OGS_SBI_HTTP_STATUS_CREATED;
}
if (status == OGS_SBI_HTTP_STATUS_CREATED)
sendmsg.http.location = ogs_sbi_server_uri(server, &header);
sendmsg.SmfRegistration = OpenAPI_smf_registration_copy(
sendmsg.SmfRegistration, sess->smf_registration);
response = ogs_sbi_build_response(&sendmsg, status);
ogs_assert(response);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
ogs_free(header.resource.component[3]);
ogs_free(sendmsg.http.location);
OpenAPI_smf_registration_free(sendmsg.SmfRegistration);
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
break;
DEFAULT
ogs_error("[%s:%d] Invalid HTTP method [%s]",
udm_ue->suci, sess->psi, recvmsg->h.method);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_FORBIDDEN, recvmsg,
"Invalid HTTP method", recvmsg->h.method));
END
break;
DEFAULT
strerror = ogs_msprintf("[%s:%d] Invalid resource name [%s]",
udm_ue->supi, sess->psi, recvmsg->h.resource.component[3]);
ogs_assert(strerror);
ogs_error("%s", strerror);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, strerror, NULL));
ogs_free(strerror);
return false;
END
return true;
}

View File

@ -33,6 +33,9 @@ bool udm_nudr_dr_handle_subscription_context(
bool udm_nudr_dr_handle_subscription_provisioned(
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
bool udm_nudr_dr_handle_smf_registration(
udm_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
#ifdef __cplusplus
}
#endif

View File

@ -53,6 +53,7 @@ int udm_sbi_open(void)
ogs_sbi_nf_service_add_version(
service, OGS_SBI_API_V1, OGS_SBI_API_V1_0_0, NULL);
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_AMF);
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_SMF);
}
if (ogs_sbi_nf_service_is_available(OGS_SBI_SERVICE_NAME_NUDM_SDM)) {
@ -93,29 +94,26 @@ bool udm_sbi_send_request(
return ogs_sbi_send_request_to_nf_instance(nf_instance, xact);
}
int udm_sbi_discover_and_send(
static int udm_sbi_discover_and_send(
ogs_sbi_object_t *sbi_object,
ogs_sbi_service_type_e service_type,
ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_request_t *(*build)(udm_ue_t *udm_ue, void *data),
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, void *data)
ogs_sbi_build_f build,
void *context, ogs_sbi_stream_t *stream, void *data)
{
ogs_sbi_xact_t *xact = NULL;
int r;
ogs_assert(service_type);
ogs_assert(udm_ue);
ogs_assert(sbi_object);
ogs_assert(stream);
ogs_assert(build);
xact = ogs_sbi_xact_add(
&udm_ue->sbi, service_type, discovery_option,
(ogs_sbi_build_f)build, udm_ue, data);
sbi_object, service_type, discovery_option,
(ogs_sbi_build_f)build, context, data);
if (!xact) {
ogs_error("udm_sbi_discover_and_send() failed");
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", udm_ue->suci));
return OGS_ERROR;
}
@ -125,6 +123,25 @@ int udm_sbi_discover_and_send(
if (r != OGS_OK) {
ogs_error("udm_sbi_discover_and_send() failed");
ogs_sbi_xact_remove(xact);
return r;
}
return OGS_OK;
}
int udm_ue_sbi_discover_and_send(
ogs_sbi_service_type_e service_type,
ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_request_t *(*build)(udm_ue_t *udm_ue, void *data),
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, void *data)
{
int r;
r = udm_sbi_discover_and_send(
&udm_ue->sbi, service_type, discovery_option,
(ogs_sbi_build_f)build, udm_ue, stream, data);
if (r != OGS_OK) {
ogs_error("udm_ue_sbi_discover_and_send() failed");
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
@ -134,3 +151,26 @@ int udm_sbi_discover_and_send(
return OGS_OK;
}
int udm_sess_sbi_discover_and_send(
ogs_sbi_service_type_e service_type,
ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_request_t *(*build)(udm_sess_t *sess, void *data),
udm_sess_t *sess, ogs_sbi_stream_t *stream, void *data)
{
int r;
r = udm_sbi_discover_and_send(
&sess->sbi, service_type, discovery_option,
(ogs_sbi_build_f)build, sess, stream, data);
if (r != OGS_OK) {
ogs_error("udm_sess_sbi_discover_and_send() failed");
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
"Cannot discover", NULL));
return r;
}
return OGS_OK;
}

View File

@ -31,11 +31,16 @@ void udm_sbi_close(void);
bool udm_sbi_send_request(
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact);
int udm_sbi_discover_and_send(
int udm_ue_sbi_discover_and_send(
ogs_sbi_service_type_e service_type,
ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_request_t *(*build)(udm_ue_t *udm_ue, void *data),
udm_ue_t *udm_ue, ogs_sbi_stream_t *stream, void *data);
int udm_sess_sbi_discover_and_send(
ogs_sbi_service_type_e service_type,
ogs_sbi_discovery_option_t *discovery_option,
ogs_sbi_request_t *(*build)(udm_sess_t *sess, void *data),
udm_sess_t *sess, ogs_sbi_stream_t *stream, void *data);
#ifdef __cplusplus
}

181
src/udm/sess-sm.c Normal file
View File

@ -0,0 +1,181 @@
/*
* Copyright (C) 2019-2022 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 "sbi-path.h"
#include "nnrf-handler.h"
#include "nudm-handler.h"
#include "nudr-handler.h"
void udm_sess_state_initial(ogs_fsm_t *s, udm_event_t *e)
{
ogs_assert(s);
OGS_FSM_TRAN(s, &udm_sess_state_operational);
}
void udm_sess_state_final(ogs_fsm_t *s, udm_event_t *e)
{
}
void udm_sess_state_operational(ogs_fsm_t *s, udm_event_t *e)
{
udm_ue_t *udm_ue = NULL;
udm_sess_t *sess = NULL;
ogs_sbi_stream_t *stream = NULL;
ogs_sbi_message_t *message = NULL;
ogs_assert(s);
ogs_assert(e);
udm_sm_debug(e);
sess = e->sess;
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
case OGS_EVENT_SBI_SERVER:
message = e->h.sbi.message;
ogs_assert(message);
stream = e->h.sbi.data;
ogs_assert(stream);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
SWITCH(message->h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_REGISTRATIONS)
SWITCH(message->h.method)
CASE(OGS_SBI_HTTP_METHOD_PUT)
udm_nudm_uecm_handle_smf_registration(
sess, stream, message);
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
udm_nudm_uecm_handle_smf_deregistration(
sess, stream, message);
break;
DEFAULT
ogs_error("[%s:%d] Invalid HTTP method [%s]",
udm_ue->suci, sess->psi, message->h.method);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_FORBIDDEN, message,
"Invalid HTTP method", message->h.method));
END
break;
DEFAULT
ogs_error("[%s:%d] Invalid resource name [%s]",
udm_ue->suci, sess->psi,
message->h.resource.component[1]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, message,
"Invalid HTTP method", message->h.method));
END
break;
DEFAULT
ogs_error("Invalid API name [%s]", message->h.service.name);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, message,
"Invalid API name", message->h.service.name));
END
break;
case OGS_EVENT_SBI_CLIENT:
message = e->h.sbi.message;
ogs_assert(message);
stream = e->h.sbi.data;
ogs_assert(stream);
SWITCH(message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NUDR_DR)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA)
SWITCH(message->h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_CONTEXT_DATA)
udm_nudr_dr_handle_smf_registration(
sess, stream, message);
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
message->h.resource.component[2]);
ogs_assert_if_reached();
END
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
message->h.resource.component[0]);
ogs_assert_if_reached();
END
break;
DEFAULT
ogs_error("[%s:%d] Invalid API name [%s]",
udm_ue->supi, sess->psi, message->h.service.name);
ogs_assert_if_reached();
END
break;
default:
ogs_error("[%s:%d] Unknown event %s",
udm_ue->supi, sess->psi, udm_event_get_name(e));
break;
}
}
void udm_sess_state_exception(ogs_fsm_t *s, udm_event_t *e)
{
udm_ue_t *udm_ue = NULL;
udm_sess_t *sess = NULL;
ogs_assert(s);
ogs_assert(e);
udm_sm_debug(e);
sess = e->sess;
ogs_assert(sess);
udm_ue = sess->udm_ue;
ogs_assert(udm_ue);
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
break;
case OGS_FSM_EXIT_SIG:
break;
default:
ogs_error("[%s:%d] Unknown event %s",
udm_ue->supi, sess->psi, udm_event_get_name(e));
break;
}
}

View File

@ -49,6 +49,7 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e)
ogs_sbi_xact_t *sbi_xact = NULL;
udm_ue_t *udm_ue = NULL;
udm_sess_t *sess = NULL;
udm_sm_debug(e);
@ -175,15 +176,44 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e)
break;
}
ogs_assert(OGS_FSM_STATE(&udm_ue->sm));
SWITCH(message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
if (message.h.resource.component[3]) {
uint8_t psi = atoi(message.h.resource.component[3]);
e->udm_ue = udm_ue;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&udm_ue->sm, e);
if (OGS_FSM_CHECK(&udm_ue->sm, udm_ue_state_exception)) {
ogs_error("[%s] State machine exception", udm_ue->suci);
udm_ue_remove(udm_ue);
}
sess = udm_sess_find_by_psi(udm_ue, psi);
if (!sess) {
sess = udm_sess_add(udm_ue, psi);
ogs_assert(sess);
ogs_debug("[%s:%d] UDM session added",
udm_ue->supi, sess->psi);
}
}
ogs_assert(sess);
ogs_assert(OGS_FSM_STATE(&sess->sm));
e->sess = sess;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&sess->sm, e);
if (OGS_FSM_CHECK(&sess->sm, udm_sess_state_exception)) {
ogs_error("[%s:%d] State machine exception",
udm_ue->suci, sess->psi);
udm_sess_remove(sess);
}
break;
DEFAULT
ogs_assert(OGS_FSM_STATE(&udm_ue->sm));
e->udm_ue = udm_ue;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&udm_ue->sm, e);
if (OGS_FSM_CHECK(&udm_ue->sm, udm_ue_state_exception)) {
ogs_error("[%s] State machine exception", udm_ue->suci);
udm_ue_remove(udm_ue);
}
END
break;
DEFAULT
@ -325,39 +355,83 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NUDR_DR)
SWITCH(message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA)
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
SWITCH(message.h.resource.component[3])
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
if (!sbi_xact) {
/* CLIENT_WAIT timer could remove SBI transaction
* before receiving SBI message */
ogs_error("SBI transaction has already been removed");
sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
if (!sbi_xact) {
/* CLIENT_WAIT timer could remove SBI transaction
* before receiving SBI message */
ogs_error("SBI transaction has already been removed");
break;
}
sess = (udm_sess_t *)sbi_xact->sbi_object;
ogs_assert(sess);
e->h.sbi.data = sbi_xact->assoc_stream;
ogs_sbi_xact_remove(sbi_xact);
sess = udm_sess_cycle(sess);
if (!sess) {
ogs_error("SESS Context has already been removed");
break;
}
udm_ue = udm_ue_cycle(sess->udm_ue);
if (!udm_ue) {
ogs_error("UE Context has already been removed");
break;
}
e->sess = sess;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&sess->sm, e);
if (OGS_FSM_CHECK(&sess->sm, udm_sess_state_exception)) {
ogs_error("[%s:%d] State machine exception",
udm_ue->suci, sess->psi);
udm_sess_remove(sess);
}
break;
}
udm_ue = (udm_ue_t *)sbi_xact->sbi_object;
ogs_assert(udm_ue);
DEFAULT
sbi_xact = e->h.sbi.data;
ogs_assert(sbi_xact);
e->h.sbi.data = sbi_xact->assoc_stream;
sbi_xact = ogs_sbi_xact_cycle(sbi_xact);
if (!sbi_xact) {
/* CLIENT_WAIT timer could remove SBI transaction
* before receiving SBI message */
ogs_error("SBI transaction has already been removed");
break;
}
ogs_sbi_xact_remove(sbi_xact);
udm_ue = (udm_ue_t *)sbi_xact->sbi_object;
ogs_assert(udm_ue);
udm_ue = udm_ue_cycle(udm_ue);
if (!udm_ue) {
ogs_error("UE(udm_ue) Context has already been removed");
break;
}
e->h.sbi.data = sbi_xact->assoc_stream;
e->udm_ue = udm_ue;
e->h.sbi.message = &message;
ogs_sbi_xact_remove(sbi_xact);
ogs_fsm_dispatch(&udm_ue->sm, e);
if (OGS_FSM_CHECK(&udm_ue->sm, udm_ue_state_exception)) {
ogs_error("[%s] State machine exception", udm_ue->suci);
udm_ue_remove(udm_ue);
}
udm_ue = udm_ue_cycle(udm_ue);
if (!udm_ue) {
ogs_error("UE Context has already been removed");
break;
}
e->udm_ue = udm_ue;
e->h.sbi.message = &message;
ogs_fsm_dispatch(&udm_ue->sm, e);
if (OGS_FSM_CHECK(&udm_ue->sm, udm_ue_state_exception)) {
ogs_error("[%s] State machine exception", udm_ue->suci);
udm_ue_remove(udm_ue);
}
END
break;
DEFAULT

View File

@ -35,6 +35,11 @@ void udm_ue_state_final(ogs_fsm_t *s, udm_event_t *e);
void udm_ue_state_operational(ogs_fsm_t *s, udm_event_t *e);
void udm_ue_state_exception(ogs_fsm_t *s, udm_event_t *e);
void udm_sess_state_initial(ogs_fsm_t *s, udm_event_t *e);
void udm_sess_state_final(ogs_fsm_t *s, udm_event_t *e);
void udm_sess_state_operational(ogs_fsm_t *s, udm_event_t *e);
void udm_sess_state_exception(ogs_fsm_t *s, udm_event_t *e);
#define udm_sm_debug(__pe) \
ogs_debug("%s(): %s", __func__, udm_event_get_name(__pe))

View File

@ -115,7 +115,8 @@ void udm_ue_state_operational(ogs_fsm_t *s, udm_event_t *e)
CASE(OGS_SBI_HTTP_METHOD_PUT)
SWITCH(message->h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_REGISTRATIONS)
udm_nudm_uecm_handle_registration(udm_ue, stream, message);
udm_nudm_uecm_handle_amf_registration(
udm_ue, stream, message);
break;
DEFAULT
@ -130,7 +131,8 @@ void udm_ue_state_operational(ogs_fsm_t *s, udm_event_t *e)
CASE(OGS_SBI_HTTP_METHOD_PATCH)
SWITCH(message->h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_REGISTRATIONS)
udm_nudm_uecm_handle_registration_update(udm_ue, stream, message);
udm_nudm_uecm_handle_amf_registration_update(
udm_ue, stream, message);
break;
DEFAULT
@ -159,7 +161,7 @@ void udm_ue_state_operational(ogs_fsm_t *s, udm_event_t *e)
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
CASE(OGS_SBI_RESOURCE_NAME_SMF_SELECT_DATA)
CASE(OGS_SBI_RESOURCE_NAME_SM_DATA)
r = udm_sbi_discover_and_send(
r = udm_ue_sbi_discover_and_send(
OGS_SBI_SERVICE_TYPE_NUDR_DR, NULL,
udm_nudr_dr_build_query_subscription_provisioned,
udm_ue, stream, message);

View File

@ -359,6 +359,48 @@ bool udr_nudr_dr_handle_subscription_context(
recvmsg, "Invalid HTTP method", recvmsg->h.method));
END
break;
CASE(OGS_SBI_RESOURCE_NAME_SMF_REGISTRATIONS)
SWITCH(recvmsg->h.method)
CASE(OGS_SBI_HTTP_METHOD_PUT)
OpenAPI_smf_registration_t *SmfRegistration;
SmfRegistration = recvmsg->SmfRegistration;
if (!SmfRegistration) {
ogs_error("[%s] No SmfRegistration", supi);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No SmfRegistration", supi));
return false;
}
memset(&sendmsg, 0, sizeof(sendmsg));
response = ogs_sbi_build_response(
&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
return true;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
memset(&sendmsg, 0, sizeof(sendmsg));
response = ogs_sbi_build_response(
&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
return true;
DEFAULT
ogs_error("Invalid HTTP method [%s]", recvmsg->h.method);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_MEHTOD_NOT_ALLOWED,
recvmsg, "Invalid HTTP method", recvmsg->h.method));
END
break;
DEFAULT
ogs_error("Invalid resource name [%s]",

View File

@ -2219,7 +2219,6 @@ static void test4_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send De-registration request */
gmmbuf = testgmm_build_de_registration_request(test_ue, 1, true, true);
ABTS_PTR_NOTNULL(tc, gmmbuf);