[SEPP] Initial Update for 5G Roaming (#2739)

[SEPP] Initial Update for 5G Roaming
This commit is contained in:
Sukchan Lee
2023-11-19 19:34:51 +09:00
committed by GitHub
parent e12b1be313
commit e92293e0af
324 changed files with 26622 additions and 14319 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
@@ -65,11 +65,6 @@ const char *ogs_event_get_name(ogs_event_t *e)
case OGS_EVENT_SBI_TIMER:
return OGS_EVENT_NAME_SBI_TIMER;
case OGS_EVENT_DBI_POLL_TIMER:
return "OGS_EVENT_DBI_POLL_TIMER";
case OGS_EVENT_DBI_MESSAGE:
return "OGS_EVENT_DBI_MESSAGE";
default:
break;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
@@ -39,9 +39,6 @@ typedef enum {
OGS_EVENT_SBI_CLIENT,
OGS_EVENT_SBI_TIMER,
OGS_EVENT_DBI_POLL_TIMER,
OGS_EVENT_DBI_MESSAGE,
OGS_MAX_NUM_OF_PROTO_EVENT,
} ogs_event_e;
@@ -63,9 +60,6 @@ typedef struct ogs_event_s {
ogs_sbi_message_t *message;
} sbi;
struct {
void *document;
} dbi;
} ogs_event_t;
#define OGS_EVENT_SIZE 256

View File

@@ -51,8 +51,6 @@ const char *ogs_timer_get_name(int timer_id)
return OGS_TIMER_NAME_SUBSCRIPTION_PATCH;
case OGS_TIMER_SBI_CLIENT_WAIT:
return OGS_TIMER_NAME_SBI_CLIENT_WAIT;
case OGS_TIMER_DBI_POLL_CHANGE_STREAM:
return "OGS_TIMER_DBI_POLL_CHANGE_STREAM";
default:
break;
}

View File

@@ -48,8 +48,6 @@ typedef enum {
OGS_TIMER_SUBSCRIPTION_PATCH,
OGS_TIMER_SBI_CLIENT_WAIT,
OGS_TIMER_DBI_POLL_CHANGE_STREAM,
OGS_MAX_NUM_OF_PROTO_TIMER,
} ogs_timer_e;

View File

@@ -34,21 +34,26 @@ uint32_t ogs_plmn_id_hexdump(void *plmn_id)
uint16_t ogs_plmn_id_mcc(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
return plmn_id->mcc1 * 100 + plmn_id->mcc2 * 10 + plmn_id->mcc3;
}
uint16_t ogs_plmn_id_mnc(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
return plmn_id->mnc1 == 0xf ? plmn_id->mnc2 * 10 + plmn_id->mnc3 :
plmn_id->mnc1 * 100 + plmn_id->mnc2 * 10 + plmn_id->mnc3;
}
uint16_t ogs_plmn_id_mnc_len(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
return plmn_id->mnc1 == 0xf ? 2 : 3;
}
void *ogs_plmn_id_build(ogs_plmn_id_t *plmn_id,
uint16_t mcc, uint16_t mnc, uint16_t mnc_len)
{
ogs_assert(plmn_id);
plmn_id->mcc1 = PLMN_ID_DIGIT1(mcc);
plmn_id->mcc2 = PLMN_ID_DIGIT2(mcc);
plmn_id->mcc3 = PLMN_ID_DIGIT3(mcc);
@@ -67,6 +72,9 @@ void *ogs_plmn_id_build(ogs_plmn_id_t *plmn_id,
void *ogs_nas_from_plmn_id(
ogs_nas_plmn_id_t *ogs_nas_plmn_id, ogs_plmn_id_t *plmn_id)
{
ogs_assert(ogs_nas_plmn_id);
ogs_assert(plmn_id);
memcpy(ogs_nas_plmn_id, plmn_id, OGS_PLMN_ID_LEN);
if (plmn_id->mnc1 != 0xf) {
ogs_nas_plmn_id->mnc1 = plmn_id->mnc1;
@@ -78,6 +86,9 @@ void *ogs_nas_from_plmn_id(
void *ogs_nas_to_plmn_id(
ogs_plmn_id_t *plmn_id, ogs_nas_plmn_id_t *ogs_nas_plmn_id)
{
ogs_assert(plmn_id);
ogs_assert(ogs_nas_plmn_id);
memcpy(plmn_id, ogs_nas_plmn_id, OGS_PLMN_ID_LEN);
if (plmn_id->mnc1 != 0xf) {
plmn_id->mnc1 = ogs_nas_plmn_id->mnc1;
@@ -87,13 +98,6 @@ void *ogs_nas_to_plmn_id(
return plmn_id;
}
char *ogs_serving_network_name_from_plmn_id(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
return ogs_msprintf("5G:mnc%03d.mcc%03d.3gppnetwork.org",
ogs_plmn_id_mnc(plmn_id), ogs_plmn_id_mcc(plmn_id));
}
char *ogs_plmn_id_mcc_string(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
@@ -124,6 +128,110 @@ char *ogs_plmn_id_to_string(ogs_plmn_id_t *plmn_id, char *buf)
return buf;
}
#define FQDN_3GPPNETWORK_ORG ".3gppnetwork.org"
#define FQDN_5GC_MNC "5gc.mnc"
#define FQDN_MCC ".mcc"
char *ogs_serving_network_name_from_plmn_id(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
return ogs_msprintf("5G:mnc%03d.mcc%03d" FQDN_3GPPNETWORK_ORG,
ogs_plmn_id_mnc(plmn_id), ogs_plmn_id_mcc(plmn_id));
}
char *ogs_home_network_domain_from_plmn_id(ogs_plmn_id_t *plmn_id)
{
ogs_assert(plmn_id);
return ogs_msprintf("5gc.mnc%03d.mcc%03d" FQDN_3GPPNETWORK_ORG,
ogs_plmn_id_mnc(plmn_id), ogs_plmn_id_mcc(plmn_id));
}
char *ogs_nrf_fqdn_from_plmn_id(ogs_plmn_id_t *plmn_id)
{
return ogs_msprintf("nrf.5gc.mnc%03d.mcc%03d" FQDN_3GPPNETWORK_ORG,
ogs_plmn_id_mnc(plmn_id), ogs_plmn_id_mcc(plmn_id));
}
char *ogs_nssf_fqdn_from_plmn_id(ogs_plmn_id_t *plmn_id)
{
return ogs_msprintf("nssf.5gc.mnc%03d.mcc%03d" FQDN_3GPPNETWORK_ORG,
ogs_plmn_id_mnc(plmn_id), ogs_plmn_id_mcc(plmn_id));
}
char *ogs_home_network_domain_from_fqdn(char *fqdn)
{
char *p = NULL;
ogs_assert(fqdn);
if (strlen(fqdn) <
strlen(FQDN_5GC_MNC "XXX" FQDN_MCC "XXX" FQDN_3GPPNETWORK_ORG)) {
return NULL;
}
p = fqdn + strlen(fqdn);
if (strncmp(p - strlen(FQDN_3GPPNETWORK_ORG),
FQDN_3GPPNETWORK_ORG, strlen(FQDN_3GPPNETWORK_ORG)) != 0) {
return NULL;
}
p -= (strlen(FQDN_3GPPNETWORK_ORG) + 3);
if (strncmp(p - strlen(FQDN_MCC),
FQDN_MCC, strlen(FQDN_MCC)) != 0) {
return NULL;
}
p -= (strlen(FQDN_MCC) + 3);
if (strncmp(p - strlen(FQDN_5GC_MNC),
FQDN_5GC_MNC, strlen(FQDN_5GC_MNC)) != 0) {
return NULL;
}
return p - strlen(FQDN_5GC_MNC);
}
uint16_t ogs_plmn_id_mcc_from_fqdn(char *fqdn)
{
char mcc[4];
char *p = NULL;
ogs_assert(fqdn);
p = ogs_home_network_domain_from_fqdn(fqdn);
if (p == NULL) {
ogs_error("Invalid FQDN [%d:%s]", (int)strlen(fqdn), fqdn);
return 0;
}
p += strlen(FQDN_5GC_MNC) + 3 + strlen(FQDN_MCC);
memcpy(mcc, p, 3);
mcc[3] = 0;
return atoi(mcc);
}
uint16_t ogs_plmn_id_mnc_from_fqdn(char *fqdn)
{
char mnc[4];
char *p = NULL;
ogs_assert(fqdn);
p = ogs_home_network_domain_from_fqdn(fqdn);
if (p == NULL) {
ogs_error("Invalid FQDN [%d:%s]", (int)strlen(fqdn), fqdn);
return 0;
}
p += strlen(FQDN_5GC_MNC);
memcpy(mnc, p, 3);
mnc[3] = 0;
return atoi(mnc);
}
uint32_t ogs_amf_id_hexdump(ogs_amf_id_t *amf_id)
{
uint32_t hex;
@@ -617,6 +725,47 @@ int ogs_ipv6prefix_from_string(uint8_t *addr6, uint8_t *prefixlen, char *string)
return OGS_OK;
}
int ogs_check_br_conf(ogs_bitrate_t *br)
{
ogs_assert(br);
if (br->downlink == 0) {
ogs_error("No Downlink");
return OGS_ERROR;
}
if (br->uplink == 0) {
ogs_error("No Uplink");
return OGS_ERROR;
}
return OGS_OK;
}
int ogs_check_qos_conf(ogs_qos_t *qos)
{
ogs_assert(qos);
if (!qos->index) {
ogs_error("No QCI");
return OGS_ERROR;
}
if (!qos->arp.priority_level) {
ogs_error("No Priority Level");
return OGS_ERROR;
}
if (!qos->arp.pre_emption_capability) {
ogs_error("No Pre-emption Capability");
return OGS_ERROR;
}
if (!qos->arp.pre_emption_vulnerability) {
ogs_error("No Pre-emption Vulnerability ");
return OGS_ERROR;
}
return OGS_OK;
}
int ogs_sockaddr_to_user_plane_ip_resource_info(
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6,
ogs_user_plane_ip_resource_info_t *info)
@@ -713,19 +862,6 @@ void ogs_subscription_data_free(ogs_subscription_data_t *subscription_data)
subscription_data->num_of_msisdn = 0;
}
void ogs_session_data_free(ogs_session_data_t *session_data)
{
int i;
ogs_assert(session_data);
if (session_data->session.name)
ogs_free(session_data->session.name);
for (i = 0; i < session_data->num_of_pcc_rule; i++)
OGS_PCC_RULE_FREE(&session_data->pcc_rule[i]);
}
void ogs_ims_data_free(ogs_ims_data_t *ims_data)
{
int i, j, k;

View File

@@ -108,6 +108,64 @@ extern "C" {
#define OGS_MAX_QOS_FLOW_ID 63
#define OGS_IMSI_STRING "imsi"
#define OGS_MSISDN_STRING "msisdn"
#define OGS_IMEISV_STRING "imeisv"
#define OGS_ACCESS_RESTRICTION_DATA_STRING "access_restriction_data"
#define OGS_SUBSCRIBER_STATUS_STRING "subscriber_status"
#define OGS_OPERATOR_DETERMINED_BARRING_STRING "operator_determined_barring"
#define OGS_NETWORK_ACCESS_MODE_STRING "network_access_mode"
#define OGS_SUBSCRIBED_RAU_TAU_TIMER_STRING "subscribed_rau_tau_timer"
#define OGS_SECURITY_STRING "security"
#define OGS_K_STRING "k"
#define OGS_OPC_STRING "opc"
#define OGS_OP_STRING "op"
#define OGS_AMF_STRING "amf"
#define OGS_RAND_STRING "rand"
#define OGS_SQN_STRING "sqn"
#define OGS_MME_HOST_STRING "mme_host"
#define OGS_MME_REALM_STRING "mme_realm"
#define OGS_MME_TIMESTAMP_STRING "mme_timestamp"
#define OGS_PURGE_FLAG_STRING "purge_flag"
#define OGS_AMBR_STRING "ambr"
#define OGS_DOWNLINK_STRING "downlink"
#define OGS_UPLINK_STRING "uplink"
#define OGS_VALUE_STRING "value"
#define OGS_UNIT_STRING "unit"
#define OGS_POLICY_STRING "policy"
#define OGS_SLICE_STRING "slice"
#define OGS_SST_STRING "sst"
#define OGS_SD_STRING "sd"
#define OGS_DEFAULT_INDICATOR_STRING "default_indicator"
#define OGS_SESSION_STRING "session"
#define OGS_NAME_STRING "name"
#define OGS_TYPE_STRING "type"
#define OGS_QOS_STRING "qos"
#define OGS_INDEX_STRING "index"
#define OGS_ARP_STRING "arp"
#define OGS_PRIORITY_LEVEL_STRING "priority_level"
#define OGS_PRE_EMPTION_CAPABILITY_STRING "pre_emption_capability"
#define OGS_PRE_EMPTION_VULNERABILITY_STRING "pre_emption_vulnerability"
#define OGS_PCC_RULE_STRING "pcc_rule"
#define OGS_MBR_STRING "mbr"
#define OGS_GBR_STRING "gbr"
#define OGS_FLOW_STRING "flow"
#define OGS_DIRECTION_STRING "direction"
#define OGS_DESCRIPTION_STRING "description"
#define OGS_SMF_STRING "smf"
#define OGS_IPV4_STRING "ipv4"
#define OGS_IPV6_STRING "ipv6"
#define OGS_UE_STRING "ue"
#define OGS_IPV4_FRAMED_ROUTES_STRING "ipv4_framed_routes"
#define OGS_IPV6_FRAMED_ROUTES_STRING "ipv6_framed_routes"
/************************************
* PLMN_ID Structure */
#define OGS_MAX_NUM_OF_PLMN 6
@@ -129,13 +187,20 @@ uint16_t ogs_plmn_id_mnc_len(ogs_plmn_id_t *plmn_id);
void *ogs_plmn_id_build(ogs_plmn_id_t *plmn_id,
uint16_t mcc, uint16_t mnc, uint16_t mnc_len);
char *ogs_serving_network_name_from_plmn_id(ogs_plmn_id_t *plmn_id);
char *ogs_plmn_id_mcc_string(ogs_plmn_id_t *plmn_id);
char *ogs_plmn_id_mnc_string(ogs_plmn_id_t *plmn_id);
#define OGS_PLMNIDSTRLEN (sizeof(ogs_plmn_id_t)*2+1)
char *ogs_plmn_id_to_string(ogs_plmn_id_t *plmn_id, char *buf);
char *ogs_serving_network_name_from_plmn_id(ogs_plmn_id_t *plmn_id);
char *ogs_home_network_domain_from_plmn_id(ogs_plmn_id_t *plmn_id);
char *ogs_nrf_fqdn_from_plmn_id(ogs_plmn_id_t *plmn_id);
char *ogs_nssf_fqdn_from_plmn_id(ogs_plmn_id_t *plmn_id);
char *ogs_home_network_domain_from_fqdn(char *fqdn);
uint16_t ogs_plmn_id_mnc_from_fqdn(char *fqdn);
uint16_t ogs_plmn_id_mcc_from_fqdn(char *fqdn);
/*************************
* NAS PLMN_ID Structure */
typedef struct ogs_nas_plmn_id_s {
@@ -331,6 +396,8 @@ typedef struct ogs_bitrate_s {
uint64_t uplink; /* bits per seconds */
} ogs_bitrate_t;
int ogs_check_br_conf(ogs_bitrate_t *br);
/**********************************
* QoS Structure */
typedef struct ogs_qos_s {
@@ -373,6 +440,8 @@ typedef struct ogs_qos_s {
ogs_bitrate_t gbr; /* Guaranteed Bit Rate (GBR) */
} ogs_qos_t;
int ogs_check_qos_conf(ogs_qos_t *qos);
/**********************************
* Flow Structure */
#define OGS_FLOW_DOWNLINK_ONLY 1
@@ -413,8 +482,8 @@ typedef struct ogs_pcc_rule_s {
#define OGS_STORE_PCC_RULE(__dST, __sRC) \
do { \
int __iNDEX; \
ogs_assert((__sRC)); \
ogs_assert((__dST)); \
ogs_assert((__sRC) != NULL); \
ogs_assert((__dST) != NULL); \
OGS_PCC_RULE_FREE(__dST); \
(__dST)->type = (__sRC)->type; \
if ((__sRC)->name) { \
@@ -441,7 +510,7 @@ typedef struct ogs_pcc_rule_s {
#define OGS_PCC_RULE_FREE(__pCCrULE) \
do { \
int __pCCrULE_iNDEX; \
ogs_assert((__pCCrULE)); \
ogs_assert((__pCCrULE) != NULL); \
if ((__pCCrULE)->id) \
ogs_free((__pCCrULE)->id); \
if ((__pCCrULE)->name) \
@@ -450,10 +519,9 @@ typedef struct ogs_pcc_rule_s {
__pCCrULE_iNDEX < (__pCCrULE)->num_of_flow; __pCCrULE_iNDEX++) { \
OGS_FLOW_FREE(&((__pCCrULE)->flow[__pCCrULE_iNDEX])); \
} \
(__pCCrULE)->num_of_flow = 0; \
memset((__pCCrULE), 0, sizeof(ogs_pcc_rule_t)); \
} while(0)
/**********************************
* PDN Structure */
typedef struct ogs_session_s {
@@ -732,7 +800,39 @@ typedef struct ogs_session_data_s {
int num_of_pcc_rule;
} ogs_session_data_t;
void ogs_session_data_free(ogs_session_data_t *session_data);
#define OGS_STORE_SESSION_DATA(__dST, __sRC) \
do { \
int rv, j; \
ogs_assert((__dST) != NULL); \
ogs_assert((__sRC) != NULL); \
OGS_SESSION_DATA_FREE(__dST); \
if ((__sRC)->session.name) { \
(__dST)->session.name = ogs_strdup((__sRC)->session.name); \
ogs_assert((__dST)->session.name); \
} \
(__dST)->session.session_type = (__sRC)->session.session_type; \
memcpy(&(__dST)->session.ambr, &(__sRC)->session.ambr, \
sizeof((__dST)->session.ambr)); \
memcpy(&(__dST)->session.qos, &(__sRC)->session.qos, \
sizeof((__dST)->session.qos)); \
(__dST)->num_of_pcc_rule = (__sRC)->num_of_pcc_rule; \
for (j = 0; j < (__dST)->num_of_pcc_rule; j++) { \
rv = ogs_check_qos_conf(&(__sRC)->pcc_rule[j].qos); \
ogs_assert(rv == OGS_OK); \
OGS_STORE_PCC_RULE(&(__dST)->pcc_rule[j], &(__sRC)->pcc_rule[j]); \
} \
} while(0)
#define OGS_SESSION_DATA_FREE(__sESSdATA) \
do { \
int i; \
ogs_assert((__sESSdATA) != NULL); \
if ((__sESSdATA)->session.name) \
ogs_free((__sESSdATA)->session.name); \
for (i = 0; i < (__sESSdATA)->num_of_pcc_rule; i++) \
OGS_PCC_RULE_FREE(&(__sESSdATA)->pcc_rule[i]); \
memset((__sESSdATA), 0, sizeof(ogs_session_data_t)); \
} while(0)
typedef struct ogs_media_sub_component_s {
uint32_t flow_number;