forked from acouzens/open5gs
parent
e01f46eb6c
commit
fc4072590e
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
189
src/smf/gsm-sm.c
189
src/smf/gsm-sm.c
|
@ -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(¶m, 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, ¶m);
|
||||
} 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, ¶m);
|
||||
}
|
||||
|
||||
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(¶m, 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, ¶m);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) -
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
138
src/udm/udm-sm.c
138
src/udm/udm-sm.c
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]",
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue