open5gs/src/smf/smf-sm.c

853 lines
29 KiB
C
Raw Normal View History

2020-04-26 19:36:05 +00:00
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "context.h"
#include "gtp-path.h"
#include "fd-path.h"
#include "pfcp-path.h"
2020-05-18 21:00:37 +00:00
#include "sbi-path.h"
2020-04-26 19:36:05 +00:00
#include "s5c-handler.h"
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
#include "gn-handler.h"
2020-04-26 19:36:05 +00:00
#include "gx-handler.h"
#include "gy-handler.h"
2020-05-18 21:00:37 +00:00
#include "nnrf-handler.h"
2021-01-18 16:48:35 +00:00
#include "namf-handler.h"
2021-11-14 12:07:56 +00:00
#include "npcf-handler.h"
2020-04-26 19:36:05 +00:00
void smf_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
smf_sm_debug(e);
ogs_assert(s);
OGS_FSM_TRAN(s, &smf_state_operational);
}
void smf_state_final(ogs_fsm_t *s, smf_event_t *e)
{
smf_sm_debug(e);
ogs_assert(s);
}
void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
{
int rv;
2020-06-17 05:22:28 +00:00
const char *api_version = NULL;
2020-04-26 19:36:05 +00:00
ogs_pkbuf_t *recvbuf = NULL;
smf_sess_t *sess = NULL;
smf_ue_t *smf_ue = NULL;
2020-04-26 19:36:05 +00:00
ogs_gtp_node_t *gnode = NULL;
ogs_gtp_xact_t *gtp_xact = NULL;
ogs_gtp2_message_t gtp2_message;
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
ogs_gtp1_message_t gtp1_message;
2020-04-26 19:36:05 +00:00
ogs_diam_gx_message_t *gx_message = NULL;
ogs_diam_gy_message_t *gy_message = NULL;
ogs_diam_s6b_message_t *s6b_message = NULL;
2020-04-26 19:36:05 +00:00
ogs_pfcp_node_t *pfcp_node = NULL;
ogs_pfcp_xact_t *pfcp_xact = NULL;
ogs_pfcp_message_t pfcp_message;
ogs_sbi_stream_t *stream = NULL;
2020-05-18 21:00:37 +00:00
ogs_sbi_request_t *sbi_request = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
ogs_sbi_subscription_t *subscription = NULL;
ogs_sbi_response_t *sbi_response = NULL;
ogs_sbi_message_t sbi_message;
ogs_sbi_xact_t *sbi_xact = NULL;
2020-06-17 05:22:28 +00:00
ogs_nas_5gs_message_t nas_message;
ogs_pkbuf_t *pkbuf = NULL;
2020-05-18 21:00:37 +00:00
2020-04-26 19:36:05 +00:00
smf_sm_debug(e);
ogs_assert(s);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
break;
2020-05-14 17:38:26 +00:00
case OGS_FSM_EXIT_SIG:
2020-04-26 19:36:05 +00:00
break;
2020-05-14 17:38:26 +00:00
2020-04-26 19:36:05 +00:00
case SMF_EVT_S5C_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
if (ogs_gtp2_parse_msg(&gtp2_message, recvbuf) != OGS_OK) {
ogs_error("ogs_gtp2_parse_msg() failed");
2020-04-26 19:36:05 +00:00
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp2_message = &gtp2_message;
2020-04-26 19:36:05 +00:00
gnode = e->gnode;
ogs_assert(gnode);
2020-04-26 19:36:05 +00:00
rv = ogs_gtp_xact_receive(gnode, &gtp2_message.h, &gtp_xact);
2020-04-26 19:36:05 +00:00
if (rv != OGS_OK) {
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp_xact = gtp_xact;
2020-04-26 19:36:05 +00:00
if (gtp2_message.h.teid != 0) {
sess = smf_sess_find_by_teid(gtp2_message.h.teid);
}
switch(gtp2_message.h.type) {
case OGS_GTP2_ECHO_REQUEST_TYPE:
smf_s5c_handle_echo_request(gtp_xact, &gtp2_message.echo_request);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_ECHO_RESPONSE_TYPE:
smf_s5c_handle_echo_response(gtp_xact, &gtp2_message.echo_response);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
if (gtp2_message.h.teid == 0) {
2020-04-26 19:36:05 +00:00
ogs_expect(!sess);
sess = smf_sess_add_by_gtp2_message(&gtp2_message);
2020-04-26 19:36:05 +00:00
if (sess)
OGS_SETUP_GTP_NODE(sess, gnode);
}
if (!sess) {
2022-04-14 02:18:21 +00:00
ogs_gtp2_send_error_message(gtp_xact, 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
if (!sess) {
ogs_gtp2_send_error_message(gtp_xact, 0,
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
2021-06-21 13:36:38 +00:00
smf_s5c_handle_modify_bearer_request(
sess, gtp_xact, recvbuf, &gtp2_message.modify_bearer_request);
2021-06-21 13:36:38 +00:00
break;
case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE:
2020-04-26 19:36:05 +00:00
smf_s5c_handle_create_bearer_response(
sess, gtp_xact, &gtp2_message.create_bearer_response);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE:
2020-04-26 19:36:05 +00:00
smf_s5c_handle_update_bearer_response(
sess, gtp_xact, &gtp2_message.update_bearer_response);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
if (!sess) {
/* TODO: NACK the message */
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
2020-04-26 19:36:05 +00:00
break;
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
2020-04-26 19:36:05 +00:00
smf_s5c_handle_bearer_resource_command(
sess, gtp_xact, &gtp2_message.bearer_resource_command);
2020-04-26 19:36:05 +00:00
break;
default:
ogs_warn("Not implmeneted(type:%d)", gtp2_message.h.type);
2020-04-26 19:36:05 +00:00
break;
}
ogs_pkbuf_free(recvbuf);
break;
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
case SMF_EVT_GN_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
if (ogs_gtp1_parse_msg(&gtp1_message, recvbuf) != OGS_OK) {
ogs_error("ogs_gtp2_parse_msg() failed");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp1_message = &gtp1_message;
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
if (gtp1_message.h.teid != 0) {
sess = smf_sess_find_by_teid(gtp1_message.h.teid);
}
gnode = e->gnode;
ogs_assert(gnode);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
rv = ogs_gtp1_xact_receive(gnode, &gtp1_message.h, &gtp_xact);
if (rv != OGS_OK) {
ogs_pkbuf_free(recvbuf);
break;
}
e->gtp_xact = gtp_xact;
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
switch(gtp1_message.h.type) {
case OGS_GTP1_ECHO_REQUEST_TYPE:
smf_gn_handle_echo_request(gtp_xact, &gtp1_message.echo_request);
break;
case OGS_GTP1_ECHO_RESPONSE_TYPE:
smf_gn_handle_echo_response(gtp_xact, &gtp1_message.echo_response);
break;
case OGS_GTP1_CREATE_PDP_CONTEXT_REQUEST_TYPE:
if (gtp1_message.h.teid == 0) {
ogs_expect(!sess);
sess = smf_sess_add_by_gtp1_message(&gtp1_message);
if (sess)
OGS_SETUP_GTP_NODE(sess, gnode);
}
if (!sess) {
ogs_gtp1_send_error_message(gtp_xact, 0,
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
break;
case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE:
if (!sess) {
ogs_gtp1_send_error_message(gtp_xact, 0,
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE,
OGS_GTP1_CAUSE_NON_EXISTENT);
break;
}
e->sess = sess;
ogs_fsm_dispatch(&sess->sm, e);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
break;
case OGS_GTP1_UPDATE_PDP_CONTEXT_REQUEST_TYPE:
smf_gn_handle_update_pdp_context_request(
sess, gtp_xact, &gtp1_message.update_pdp_context_request);
break;
case OGS_GTP1_ERROR_INDICATION_TYPE:
2022-05-14 21:27:54 +00:00
/* TS 29.060 10.1.1.4 dst port shall be the userplane port (2152) */
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
ogs_error("Rx unexpected Error Indication in GTPC port");
break;
default:
ogs_warn("Not implmeneted(type:%d)", gtp1_message.h.type);
break;
}
ogs_pkbuf_free(recvbuf);
break;
2020-04-26 19:36:05 +00:00
case SMF_EVT_GX_MESSAGE:
ogs_assert(e);
gx_message = e->gx_message;
2020-04-26 19:36:05 +00:00
ogs_assert(gx_message);
sess = e->sess;
ogs_assert(sess);
switch(gx_message->cmd_code) {
case OGS_DIAM_GX_CMD_CODE_CREDIT_CONTROL:
switch(gx_message->cc_request_type) {
case OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_fsm_dispatch(&sess->sm, e);
2020-04-26 19:36:05 +00:00
break;
case OGS_DIAM_GX_CC_REQUEST_TYPE_TERMINATION_REQUEST:
ogs_fsm_dispatch(&sess->sm, e);
2020-04-26 19:36:05 +00:00
break;
default:
2021-01-18 16:48:35 +00:00
ogs_error("Not implemented(%d)", gx_message->cc_request_type);
2020-04-26 19:36:05 +00:00
break;
}
break;
case OGS_DIAM_GX_CMD_RE_AUTH:
smf_gx_handle_re_auth_request(sess, gx_message);
break;
default:
ogs_error("Invalid type(%d)", gx_message->cmd_code);
break;
}
2021-01-01 02:07:08 +00:00
ogs_session_data_free(&gx_message->session_data);
ogs_free(gx_message);
2020-04-26 19:36:05 +00:00
break;
case SMF_EVT_GY_MESSAGE:
ogs_assert(e);
gy_message = e->gy_message;
ogs_assert(gy_message);
sess = e->sess;
ogs_assert(sess);
switch(gy_message->cmd_code) {
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
switch(gy_message->cc_request_type) {
case OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST:
ogs_fsm_dispatch(&sess->sm, e);
break;
case OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST:
ogs_assert(e->pfcp_xact);
smf_gy_handle_cca_update_request(
sess, gy_message, e->pfcp_xact);
break;
case OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST:
ogs_fsm_dispatch(&sess->sm, e);
break;
default:
ogs_error("Not implemented(%d)", gy_message->cc_request_type);
break;
}
break;
case OGS_DIAM_GY_CMD_RE_AUTH:
smf_gy_handle_re_auth_request(sess, gy_message);
break;
default:
ogs_error("Invalid type(%d)", gy_message->cmd_code);
break;
}
ogs_free(gy_message);
break;
case SMF_EVT_S6B_MESSAGE:
ogs_assert(e);
s6b_message = e->s6b_message;
ogs_assert(s6b_message);
sess = e->sess;
ogs_assert(sess);
switch(s6b_message->cmd_code) {
case OGS_DIAM_S6B_CMD_SESSION_TERMINATION:
ogs_fsm_dispatch(&sess->sm, e);
break;
default:
ogs_error("Invalid type(%d)", s6b_message->cmd_code);
break;
}
ogs_free(s6b_message);
break;
2020-04-26 19:36:05 +00:00
case SMF_EVT_N4_MESSAGE:
ogs_assert(e);
recvbuf = e->pkbuf;
ogs_assert(recvbuf);
pfcp_node = e->pfcp_node;
ogs_assert(pfcp_node);
2020-05-14 17:38:26 +00:00
ogs_assert(OGS_FSM_STATE(&pfcp_node->sm));
2020-04-26 19:36:05 +00:00
if (ogs_pfcp_parse_msg(&pfcp_message, recvbuf) != OGS_OK) {
ogs_error("ogs_pfcp_parse_msg() failed");
ogs_pkbuf_free(recvbuf);
break;
}
rv = ogs_pfcp_xact_receive(pfcp_node, &pfcp_message.h, &pfcp_xact);
if (rv != OGS_OK) {
ogs_pkbuf_free(recvbuf);
break;
}
e->pfcp_message = &pfcp_message;
e->pfcp_xact = pfcp_xact;
e->gtp2_message = NULL;
if (pfcp_xact->gtpbuf) {
rv = ogs_gtp2_parse_msg(&gtp2_message, pfcp_xact->gtpbuf);
e->gtp2_message = &gtp2_message;
}
2020-04-26 19:36:05 +00:00
ogs_fsm_dispatch(&pfcp_node->sm, e);
if (OGS_FSM_CHECK(&pfcp_node->sm, smf_pfcp_state_exception)) {
ogs_error("PFCP state machine exception");
break;
}
ogs_pkbuf_free(recvbuf);
break;
case SMF_EVT_N4_TIMER:
case SMF_EVT_N4_NO_HEARTBEAT:
2020-05-18 21:00:37 +00:00
ogs_assert(e);
2020-04-26 19:36:05 +00:00
pfcp_node = e->pfcp_node;
ogs_assert(pfcp_node);
ogs_assert(OGS_FSM_STATE(&pfcp_node->sm));
ogs_fsm_dispatch(&pfcp_node->sm, e);
break;
2020-05-18 21:00:37 +00:00
case SMF_EVT_SBI_SERVER:
sbi_request = e->sbi.request;
ogs_assert(sbi_request);
stream = e->sbi.data;
ogs_assert(stream);
2020-05-18 21:00:37 +00:00
rv = ogs_sbi_parse_request(&sbi_message, sbi_request);
if (rv != OGS_OK) {
/* 'sbi_message' buffer is released in ogs_sbi_parse_request() */
ogs_error("cannot parse HTTP sbi_message");
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
NULL, "cannot parse HTTP sbi_message", NULL));
2020-05-18 21:00:37 +00:00
break;
}
2020-06-17 05:22:28 +00:00
SWITCH(sbi_message.h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
api_version = OGS_SBI_API_V2;
break;
DEFAULT
api_version = OGS_SBI_API_V1;
END
ogs_assert(api_version);
if (strcmp(sbi_message.h.api.version, api_version) != 0) {
2020-05-18 21:00:37 +00:00
ogs_error("Not supported version [%s]", sbi_message.h.api.version);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
&sbi_message, "Not supported version", NULL));
2020-05-18 21:00:37 +00:00
ogs_sbi_message_free(&sbi_message);
break;
}
SWITCH(sbi_message.h.service.name)
2020-06-04 18:12:05 +00:00
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
2020-05-18 21:00:37 +00:00
2020-06-04 18:12:05 +00:00
SWITCH(sbi_message.h.resource.component[0])
2020-05-18 21:00:37 +00:00
CASE(OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY)
SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
smf_nnrf_handle_nf_status_notify(stream, &sbi_message);
2020-05-18 21:00:37 +00:00
break;
DEFAULT
2021-01-18 16:48:35 +00:00
ogs_error("Invalid HTTP method [%s]", sbi_message.h.method);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
2021-01-18 16:48:35 +00:00
OGS_SBI_HTTP_STATUS_FORBIDDEN, &sbi_message,
2021-06-06 13:35:46 +00:00
"Invalid HTTP method", sbi_message.h.method));
2020-05-18 21:00:37 +00:00
END
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
2020-06-04 18:12:05 +00:00
sbi_message.h.resource.component[0]);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
2020-06-17 05:22:28 +00:00
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"Invalid resource name",
2021-06-06 13:35:46 +00:00
sbi_message.h.resource.component[0]));
2020-06-17 05:22:28 +00:00
END
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_SM_CONTEXTS)
SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
SWITCH(sbi_message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
CASE(OGS_SBI_RESOURCE_NAME_RELEASE)
if (!sbi_message.h.resource.component[1]) {
ogs_error("No smContextRef [%s]",
2021-11-14 12:07:56 +00:00
sbi_message.h.resource.component[1]);
smf_sbi_send_sm_context_update_error(stream,
2020-06-17 05:22:28 +00:00
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
"No smContextRef",
2021-11-14 12:07:56 +00:00
sbi_message.h.resource.component[1],
2020-07-02 05:50:23 +00:00
NULL, NULL);
2020-06-17 05:22:28 +00:00
break;
}
sess = smf_sess_find_by_sm_context_ref(
sbi_message.h.resource.component[1]);
if (!sess) {
2020-07-04 03:14:48 +00:00
ogs_warn("Not found [%s]", sbi_message.h.uri);
smf_sbi_send_sm_context_update_error(stream,
2020-07-02 05:50:23 +00:00
OGS_SBI_HTTP_STATUS_NOT_FOUND, "Not found",
2020-07-04 03:14:48 +00:00
sbi_message.h.uri, NULL, NULL);
2020-06-17 05:22:28 +00:00
}
break;
DEFAULT
sess = smf_sess_add_by_sbi_message(&sbi_message);
ogs_assert(sess);
END
break;
DEFAULT
ogs_error("Invalid HTTP method [%s]", sbi_message.h.method);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
2020-06-17 05:22:28 +00:00
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
2021-06-06 13:35:46 +00:00
"Invalid HTTP method", sbi_message.h.method));
2020-06-17 05:22:28 +00:00
break;
END
if (sess) {
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
2020-06-17 05:22:28 +00:00
ogs_assert(OGS_FSM_STATE(&sess->sm));
e->sess = sess;
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&sess->sm, e);
}
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message.h.resource.component[0]);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
2020-06-17 05:22:28 +00:00
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"Invalid resource name",
2021-06-06 13:35:46 +00:00
sbi_message.h.resource.component[0]));
2020-05-18 21:00:37 +00:00
END
break;
2020-12-11 19:03:20 +00:00
CASE(OGS_SBI_SERVICE_NAME_NSMF_CALLBACK)
2021-01-18 16:48:35 +00:00
SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_N1_N2_FAILURE_NOTIFY)
2021-11-14 12:07:56 +00:00
smf_namf_comm_handle_n1_n2_message_transfer_failure_notify(
2021-01-18 16:48:35 +00:00
stream, &sbi_message);
break;
CASE(OGS_SBI_RESOURCE_NAME_SM_POLICY_NOTIFY)
2021-11-14 12:07:56 +00:00
if (!sbi_message.h.resource.component[1]) {
ogs_error("No smContextRef [%s]",
sbi_message.h.resource.component[1]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"No smContextRef",
sbi_message.h.resource.component[1]));
break;
}
sess = smf_sess_find_by_sm_context_ref(
sbi_message.h.resource.component[1]);
if (!sess) {
ogs_warn("Not found [%s]", sbi_message.h.uri);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_NOT_FOUND, &sbi_message,
"Not found",
sbi_message.h.resource.component[1]));
break;
}
SWITCH(sbi_message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_UPDATE)
smf_npcf_smpolicycontrol_handle_update_notify(
sess, stream, &sbi_message);
break;
CASE(OGS_SBI_RESOURCE_NAME_TERMINATE)
smf_npcf_smpolicycontrol_handle_terminate_notify(
sess, stream, &sbi_message);
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message.h.resource.component[0]);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"Invalid resource name",
sbi_message.h.resource.component[0]));
END
break;
2020-12-11 19:03:20 +00:00
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message.h.resource.component[0]);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"Invalid resource name",
2021-06-06 13:35:46 +00:00
sbi_message.h.resource.component[0]));
2020-12-11 19:03:20 +00:00
END
break;
2020-05-18 21:00:37 +00:00
DEFAULT
ogs_error("Invalid API name [%s]", sbi_message.h.service.name);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
2020-06-17 05:22:28 +00:00
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
2021-06-06 13:35:46 +00:00
"Invalid API name", sbi_message.h.service.name));
2020-05-18 21:00:37 +00:00
END
/* In lib/sbi/server.c, notify_completed() releases 'request' buffer. */
ogs_sbi_message_free(&sbi_message);
break;
case SMF_EVT_SBI_CLIENT:
ogs_assert(e);
sbi_response = e->sbi.response;
ogs_assert(sbi_response);
rv = ogs_sbi_parse_response(&sbi_message, sbi_response);
if (rv != OGS_OK) {
ogs_error("cannot parse HTTP response");
ogs_sbi_message_free(&sbi_message);
ogs_sbi_response_free(sbi_response);
break;
}
2020-06-17 05:22:28 +00:00
SWITCH(sbi_message.h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
api_version = OGS_SBI_API_V2;
break;
DEFAULT
api_version = OGS_SBI_API_V1;
END
ogs_assert(api_version);
if (strcmp(sbi_message.h.api.version, api_version) != 0) {
2020-05-18 21:00:37 +00:00
ogs_error("Not supported version [%s]", sbi_message.h.api.version);
ogs_sbi_message_free(&sbi_message);
ogs_sbi_response_free(sbi_response);
break;
}
SWITCH(sbi_message.h.service.name)
2020-06-04 18:12:05 +00:00
CASE(OGS_SBI_SERVICE_NAME_NNRF_NFM)
2020-05-18 21:00:37 +00:00
2020-06-04 18:12:05 +00:00
SWITCH(sbi_message.h.resource.component[0])
2020-05-18 21:00:37 +00:00
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&nf_instance->sm, e);
break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)
subscription = e->sbi.data;
ogs_assert(subscription);
SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_POST)
if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_CREATED ||
sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK) {
smf_nnrf_handle_nf_status_subscribe(
subscription, &sbi_message);
} else {
ogs_error("HTTP response error : %d",
sbi_message.res_status);
}
break;
CASE(OGS_SBI_HTTP_METHOD_DELETE)
if (sbi_message.res_status ==
OGS_SBI_HTTP_STATUS_NO_CONTENT) {
ogs_sbi_subscription_remove(subscription);
} else {
ogs_error("HTTP response error : %d",
sbi_message.res_status);
}
break;
DEFAULT
ogs_error("Invalid HTTP method [%s]", sbi_message.h.method);
2020-06-04 18:12:05 +00:00
ogs_assert_if_reached();
2020-05-18 21:00:37 +00:00
END
break;
2020-05-18 21:00:37 +00:00
DEFAULT
ogs_error("Invalid resource name [%s]",
2020-06-04 18:12:05 +00:00
sbi_message.h.resource.component[0]);
ogs_assert_if_reached();
2020-05-18 21:00:37 +00:00
END
break;
2020-06-04 18:12:05 +00:00
CASE(OGS_SBI_SERVICE_NAME_NNRF_DISC)
SWITCH(sbi_message.h.resource.component[0])
2020-05-18 21:00:37 +00:00
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
sbi_xact = e->sbi.data;
ogs_assert(sbi_xact);
2020-06-17 05:22:28 +00:00
SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_GET)
2020-06-22 03:07:14 +00:00
if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK)
smf_nnrf_handle_nf_discover(sbi_xact, &sbi_message);
2020-06-22 03:07:14 +00:00
else
2020-06-17 05:22:28 +00:00
ogs_error("HTTP response error [%d]",
sbi_message.res_status);
break;
DEFAULT
ogs_error("Invalid HTTP method [%s]", sbi_message.h.method);
ogs_assert_if_reached();
END
2020-05-18 21:00:37 +00:00
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
2020-06-04 18:12:05 +00:00
sbi_message.h.resource.component[0]);
ogs_assert_if_reached();
2020-05-18 21:00:37 +00:00
END
break;
2020-06-17 05:22:28 +00:00
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
2020-12-11 19:03:20 +00:00
CASE(OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL)
2020-06-17 05:22:28 +00:00
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
sbi_xact = e->sbi.data;
ogs_assert(sbi_xact);
sess = (smf_sess_t *)sbi_xact->sbi_object;
2020-06-17 05:22:28 +00:00
ogs_assert(sess);
e->sbi.data = sbi_xact->assoc_stream;
e->sbi.state = sbi_xact->state;
ogs_sbi_xact_remove(sbi_xact);
2020-07-30 03:26:12 +00:00
sess = smf_sess_cycle(sess);
if (!sess) {
ogs_error("Session has already been removed");
break;
}
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
2020-07-30 03:26:12 +00:00
smf_ue = smf_ue_cycle(smf_ue);
ogs_assert(smf_ue);
2020-06-17 05:22:28 +00:00
ogs_assert(OGS_FSM_STATE(&sess->sm));
e->sess = sess;
e->sbi.message = &sbi_message;
2020-06-22 03:07:14 +00:00
2020-06-17 05:22:28 +00:00
ogs_fsm_dispatch(&sess->sm, e);
break;
2020-05-18 21:00:37 +00:00
DEFAULT
2020-07-09 05:38:09 +00:00
ogs_error("Invalid service name [%s]", sbi_message.h.service.name);
ogs_assert_if_reached();
2020-05-18 21:00:37 +00:00
END
ogs_sbi_message_free(&sbi_message);
ogs_sbi_response_free(sbi_response);
break;
case SMF_EVT_SBI_TIMER:
ogs_assert(e);
switch(e->timer_id) {
case SMF_TIMER_NF_INSTANCE_REGISTRATION_INTERVAL:
case SMF_TIMER_NF_INSTANCE_HEARTBEAT_INTERVAL:
2020-07-27 01:02:40 +00:00
case SMF_TIMER_NF_INSTANCE_NO_HEARTBEAT:
2020-05-18 21:00:37 +00:00
case SMF_TIMER_NF_INSTANCE_VALIDITY:
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
ogs_fsm_dispatch(&nf_instance->sm, e);
2020-06-04 18:12:05 +00:00
if (OGS_FSM_CHECK(&nf_instance->sm, smf_nf_state_exception))
ogs_error("State machine exception [%d]", e->timer_id);
2020-05-18 21:00:37 +00:00
break;
case SMF_TIMER_SUBSCRIPTION_VALIDITY:
subscription = e->sbi.data;
ogs_assert(subscription);
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_nnrf_nfm_send_nf_status_subscribe(subscription->client,
smf_self()->nf_type, subscription->req_nf_instance_id,
2021-06-06 13:35:46 +00:00
subscription->subscr_cond.nf_type));
2020-05-18 21:00:37 +00:00
ogs_info("Subscription validity expired [%s]", subscription->id);
ogs_sbi_subscription_remove(subscription);
break;
2020-06-17 05:22:28 +00:00
case SMF_TIMER_SBI_CLIENT_WAIT:
sbi_xact = e->sbi.data;
ogs_assert(sbi_xact);
stream = sbi_xact->assoc_stream;
/* Here, we should not use ogs_assert(stream)
* since 'namf-comm' service has no an associated stream. */
2020-06-17 05:22:28 +00:00
ogs_sbi_xact_remove(sbi_xact);
2020-06-22 03:07:14 +00:00
2020-06-17 05:22:28 +00:00
ogs_error("Cannot receive SBI message");
if (stream) {
2021-06-06 13:35:46 +00:00
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL,
2021-06-06 13:35:46 +00:00
"Cannot receive SBI message", NULL));
}
2020-06-17 05:22:28 +00:00
break;
2020-05-18 21:00:37 +00:00
default:
ogs_error("Unknown timer[%s:%d]",
smf_timer_get_name(e->timer_id), e->timer_id);
}
break;
2020-06-17 05:22:28 +00:00
case SMF_EVT_5GSM_MESSAGE:
sess = e->sess;
ogs_assert(sess);
stream = e->sbi.data;
ogs_assert(stream);
2020-06-17 05:22:28 +00:00
pkbuf = e->pkbuf;
ogs_assert(pkbuf);
if (ogs_nas_5gsm_decode(&nas_message, pkbuf) != OGS_OK) {
ogs_error("ogs_nas_5gsm_decode() failed");
ogs_pkbuf_free(pkbuf);
return;
}
ogs_assert(sess);
ogs_assert(OGS_FSM_STATE(&sess->sm));
2022-05-14 21:27:54 +00:00
e->nas.message = &nas_message;
ogs_fsm_dispatch(&sess->sm, e);
2020-06-17 05:22:28 +00:00
ogs_pkbuf_free(pkbuf);
break;
case SMF_EVT_NGAP_MESSAGE:
sess = e->sess;
ogs_assert(sess);
stream = e->sbi.data;
ogs_assert(stream);
2020-06-17 05:22:28 +00:00
pkbuf = e->pkbuf;
ogs_assert(pkbuf);
ogs_assert(e->ngap.type);
ogs_assert(sess);
ogs_assert(OGS_FSM_STATE(&sess->sm));
ogs_fsm_dispatch(&sess->sm, e);
ogs_pkbuf_free(pkbuf);
break;
2020-04-26 19:36:05 +00:00
default:
ogs_error("No handler for event %s", smf_event_get_name(e));
break;
}
}