[SMF] Apply 5G Core into GSM (#1498)

This commit is contained in:
Sukchan Lee 2022-05-15 06:27:54 +09:00
parent c5715d6695
commit c391ac1334
11 changed files with 869 additions and 407 deletions

View File

@ -8,7 +8,7 @@ If you find Open5GS useful for work, please consider supporting this Open Source
<tr>
<td align="center" valign="middle">
<a href="https://teletresearch.com/" target="_blank">
<img width="320px" src="https://open5gs.org/assets/img/Telet-logo-v2.png">
<img width="400px" src="https://open5gs.org/assets/img/Telet-logo-v2.png">
</a>
</td>
</tr>
@ -21,7 +21,7 @@ If you find Open5GS useful for work, please consider supporting this Open Source
<tr>
<td align="center" valign="middle">
<a href="http://wavemobile.com/" target="_blank">
<img width="250px" src="https://open5gs.org/assets/img/Wavemobile-Logo-Mark-RGB.png">
<img width="222px" src="https://open5gs.org/assets/img/Wavemobile-Logo-Mark-RGB.png">
</a>
</td>
</tr>

View File

@ -1053,6 +1053,9 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, uint8_t rat_type)
sess->gtp_rat_type = rat_type;
ogs_assert(sess->gtp_rat_type);
/* Set EPC */
sess->epc = true;
memset(&e, 0, sizeof(e));
e.sess = sess;
ogs_fsm_create(&sess->sm, smf_gsm_state_initial, smf_gsm_state_final);

View File

@ -228,6 +228,8 @@ typedef struct smf_sess_s {
uint32_t s6b_sta_err; /* S6B CCA RXed error code */
} sm_data;
bool epc; /**< EPC or 5GC */
ogs_pfcp_sess_t pfcp; /* PFCP session context */
uint64_t smpolicycontrol_features; /* SBI features */

File diff suppressed because it is too large Load Diff

View File

@ -141,7 +141,8 @@ static int sbi_status_from_pfcp(uint8_t pfcp_cause)
return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
}
/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success, other cause value on failure */
/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success,
* other cause value on failure */
uint8_t smf_5gc_n4_handle_session_establishment_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_establishment_response_t *rsp)
@ -599,29 +600,17 @@ void smf_5gc_n4_handle_session_modification_response(
}
}
void smf_5gc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
int smf_5gc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger,
ogs_pfcp_session_deletion_response_t *rsp)
{
int status = 0;
int trigger;
ogs_sbi_stream_t *stream = NULL;
ogs_sbi_message_t sendmsg;
ogs_sbi_response_t *response = NULL;
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Deletion Response [5gc]");
stream = xact->assoc_stream;
trigger = xact->delete_trigger;
ogs_assert(rsp);
ogs_assert(trigger);
ogs_pfcp_xact_commit(xact);
status = OGS_SBI_HTTP_STATUS_OK;
if (!sess) {
@ -662,59 +651,16 @@ void smf_5gc_n4_handle_session_deletion_response(
ogs_error("%s", strerror);
ogs_free(strerror);
return;
return status;
}
ogs_assert(sess);
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));
OGS_FSM_TRAN(&sess->sm, smf_gsm_state_session_will_release);
} 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 status;
}
/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success, other cause value on failure */
/* Returns OGS_PFCP_CAUSE_REQUEST_ACCEPTED on success,
* other cause value on failure */
uint8_t smf_epc_n4_handle_session_establishment_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_establishment_response_t *rsp)
@ -1109,7 +1055,8 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
bearer = smf_default_bearer_in_sess(sess);
for (i = 0; i < OGS_ARRAY_SIZE(rsp->usage_report); i++) {
ogs_pfcp_tlv_usage_report_session_deletion_response_t *use_rep = &rsp->usage_report[i];
ogs_pfcp_tlv_usage_report_session_deletion_response_t *use_rep =
&rsp->usage_report[i];
uint32_t urr_id;
ogs_pfcp_volume_measurement_t volume;
if (use_rep->presence == 0)
@ -1119,7 +1066,8 @@ uint8_t smf_epc_n4_handle_session_deletion_response(
urr_id = use_rep->urr_id.u32;
if (!bearer || !bearer->urr || bearer->urr->id != urr_id)
continue;
ogs_pfcp_parse_volume_measurement(&volume, &use_rep->volume_measurement);
ogs_pfcp_parse_volume_measurement(
&volume, &use_rep->volume_measurement);
if (volume.ulvol)
sess->gy.ul_octets += volume.uplink_volume;
if (volume.dlvol)
@ -1270,7 +1218,8 @@ void smf_n4_handle_session_report_request(
if (report_type.usage_report) {
bearer = smf_default_bearer_in_sess(sess);
for (i = 0; i < OGS_ARRAY_SIZE(pfcp_req->usage_report); i++) {
ogs_pfcp_tlv_usage_report_session_report_request_t *use_rep = &pfcp_req->usage_report[i];
ogs_pfcp_tlv_usage_report_session_report_request_t *use_rep =
&pfcp_req->usage_report[i];
uint32_t urr_id;
ogs_pfcp_volume_measurement_t volume;
if (use_rep->presence == 0)
@ -1280,7 +1229,8 @@ void smf_n4_handle_session_report_request(
urr_id = use_rep->urr_id.u32;
if (!bearer || !bearer->urr || bearer->urr->id != urr_id)
continue;
ogs_pfcp_parse_volume_measurement(&volume, &use_rep->volume_measurement);
ogs_pfcp_parse_volume_measurement(
&volume, &use_rep->volume_measurement);
if (volume.ulvol)
sess->gy.ul_octets += volume.uplink_volume;
if (volume.dlvol)
@ -1289,7 +1239,8 @@ void smf_n4_handle_session_report_request(
}
switch(smf_use_gy_iface()) {
case 1:
smf_gy_send_ccr(sess, pfcp_xact, OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST);
smf_gy_send_ccr(sess, pfcp_xact,
OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST);
break;
case -1:
ogs_error("No Gy Diameter Peer");

View File

@ -32,8 +32,8 @@ uint8_t smf_5gc_n4_handle_session_establishment_response(
void smf_5gc_n4_handle_session_modification_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_modification_response_t *rsp);
void smf_5gc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
int smf_5gc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger,
ogs_pfcp_session_deletion_response_t *rsp);
uint8_t smf_epc_n4_handle_session_establishment_response(

View File

@ -590,20 +590,6 @@ cleanup:
return false;
}
bool smf_npcf_smpolicycontrol_handle_delete(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int state,
ogs_sbi_message_t *recvmsg)
{
int trigger = state;
ogs_assert(trigger);
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_deletion_request(sess, stream, trigger));
return true;
}
bool smf_npcf_smpolicycontrol_handle_update_notify(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{

View File

@ -29,9 +29,6 @@ extern "C" {
bool smf_npcf_smpolicycontrol_handle_create(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int state,
ogs_sbi_message_t *recvmsg);
bool smf_npcf_smpolicycontrol_handle_delete(
smf_sess_t *sess, ogs_sbi_stream_t *stream, int state,
ogs_sbi_message_t *recvmsg);
bool smf_npcf_smpolicycontrol_handle_update_notify(
smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
bool smf_npcf_smpolicycontrol_handle_terminate_notify(

View File

@ -245,7 +245,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
sess, gtp_xact, &gtp1_message.update_pdp_context_request);
break;
case OGS_GTP1_ERROR_INDICATION_TYPE:
/* TS 29.060 10.1.1.4 dst port shall be the user plane port (2152) */
/* TS 29.060 10.1.1.4 dst port shall be the userplane port (2152) */
ogs_error("Rx unexpected Error Indication in GTPC port");
break;
default:
@ -514,10 +514,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
e->sess = sess;
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&sess->sm, e);
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
ogs_error("[%s] State machine exception", smf_ue->supi);
SMF_SESS_CLEAR(sess);
}
}
break;
@ -743,10 +739,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&sess->sm, e);
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
ogs_error("[%s] State machine exception", smf_ue->supi);
SMF_SESS_CLEAR(sess);
}
break;
DEFAULT
@ -830,22 +822,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(sess);
ogs_assert(OGS_FSM_STATE(&sess->sm));
sess->pti = nas_message.gsm.h.procedure_transaction_identity;
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));
SMF_SESS_CLEAR(sess);
break;
default:
e->nas.message = &nas_message;
ogs_fsm_dispatch(&sess->sm, e);
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
ogs_error("State machine exception");
SMF_SESS_CLEAR(sess);
}
}
e->nas.message = &nas_message;
ogs_fsm_dispatch(&sess->sm, e);
ogs_pkbuf_free(pkbuf);
break;
@ -863,10 +841,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(OGS_FSM_STATE(&sess->sm));
ogs_fsm_dispatch(&sess->sm, e);
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
ogs_error("State machine exception");
SMF_SESS_CLEAR(sess);
}
ogs_pkbuf_free(pkbuf);
break;

View File

@ -43,11 +43,13 @@ void smf_nf_state_exception(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_final(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial_wait_auth(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_initial_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_wait_5gc_sm_policy_association(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_release_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_release_wait_auth(ogs_fsm_t *s, smf_event_t *e);
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_session_will_release(ogs_fsm_t *s, smf_event_t *e);
void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e);

View File

@ -27,8 +27,6 @@ extern "C" {
#endif
upf_sess_t *upf_sess_find_by_ue_ip_address(ogs_pkbuf_t *pkbuf);
ogs_pfcp_rule_t *upf_pdr_rule_find_by_packet(
ogs_pfcp_pdr_t *pdr, ogs_pkbuf_t *pkbuf);
#ifdef __cplusplus
}