mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-03 21:43:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			934 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			934 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						||
 * Copyright (C) 2019-2023 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/>.
 | 
						||
 */
 | 
						||
 | 
						||
#if !defined(OGS_PROTO_INSIDE) && !defined(OGS_PROTO_COMPILATION)
 | 
						||
#error "This header cannot be included directly."
 | 
						||
#endif
 | 
						||
 | 
						||
#ifndef OGS_PROTO_TYPES_H
 | 
						||
#define OGS_PROTO_TYPES_H
 | 
						||
 | 
						||
#ifdef __cplusplus
 | 
						||
extern "C" {
 | 
						||
#endif /* __cplusplus */
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_SESS             4   /* Num of APN(Session) per UE */
 | 
						||
#define OGS_MAX_NUM_OF_BEARER           4   /* Num of Bearer per Session */
 | 
						||
#define OGS_BEARER_PER_UE               8   /* Num of Bearer per UE */
 | 
						||
#define OGS_MAX_NUM_OF_PACKET_BUFFER    64  /* Num of PacketBuffer per UE */
 | 
						||
 | 
						||
/*
 | 
						||
 * The array of TLV messages is limited to 8.
 | 
						||
 * So, Flow(PDI.SDF_Filter) in PDR is limited to 8.
 | 
						||
 *
 | 
						||
 * However, the number of flow in bearer context seems to need more than 16.
 | 
						||
 *
 | 
						||
 * Therefore, the maximum number of flows of messages is defined as 8,
 | 
						||
 * and the maximum number of flows stored by the context is 16.
 | 
						||
 */
 | 
						||
#define OGS_MAX_NUM_OF_FLOW_IN_PDR      8
 | 
						||
#define OGS_MAX_NUM_OF_FLOW_IN_GTP      OGS_MAX_NUM_OF_FLOW_IN_PDR
 | 
						||
#define OGS_MAX_NUM_OF_FLOW_IN_NAS      OGS_MAX_NUM_OF_FLOW_IN_PDR
 | 
						||
#define OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE OGS_MAX_NUM_OF_FLOW_IN_PDR
 | 
						||
#define OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT OGS_MAX_NUM_OF_FLOW_IN_PDR
 | 
						||
#define OGS_MAX_NUM_OF_FLOW_IN_BEARER   16
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_GTPU_RESOURCE    4
 | 
						||
#define OGS_MAX_NUM_OF_FRAMED_ROUTES_IN_PDI 8
 | 
						||
 | 
						||
#define OGS_PLMN_ID_LEN                 3
 | 
						||
#define OGS_MAX_PLMN_ID_BCD_LEN         6
 | 
						||
 | 
						||
#define OGS_CHRGCHARS_LEN               2
 | 
						||
 | 
						||
#define OGS_MSIN_LEN                    5
 | 
						||
 | 
						||
#define OGS_BCD_TO_BUFFER_LEN(x)        (((x)+1)/2)
 | 
						||
#define OGS_MAX_IMSI_BCD_LEN            15
 | 
						||
#define OGS_MAX_IMSI_LEN                \
 | 
						||
    OGS_BCD_TO_BUFFER_LEN(OGS_MAX_IMSI_BCD_LEN)
 | 
						||
 | 
						||
#define OGS_MAX_IMEISV_BCD_LEN          16
 | 
						||
#define OGS_MAX_IMEISV_LEN              \
 | 
						||
    OGS_BCD_TO_BUFFER_LEN(OGS_MAX_IMEISV_BCD_LEN)
 | 
						||
 | 
						||
#define OGS_MAX_MSISDN_BCD_LEN          15
 | 
						||
#define OGS_MAX_MSISDN_LEN              \
 | 
						||
    OGS_BCD_TO_BUFFER_LEN(OGS_MAX_MSISDN_BCD_LEN)
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_CELL_ID          16
 | 
						||
#define OGS_MAX_NUM_OF_ENB_ID           16
 | 
						||
#define OGS_MAX_NUM_OF_DNN              16
 | 
						||
#define OGS_MAX_NUM_OF_APN              OGS_MAX_NUM_OF_DNN
 | 
						||
#define OGS_MAX_NUM_OF_HOSTNAME         16
 | 
						||
#define OGS_MAX_DNN_LEN                 100
 | 
						||
#define OGS_MAX_APN_LEN                 OGS_MAX_DNN_LEN
 | 
						||
#define OGS_MAX_PCO_LEN                 251
 | 
						||
#define OGS_MAX_EPCO_LEN                65535
 | 
						||
#define OGS_MAX_FQDN_LEN                256
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_ALGORITHM        8
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_SERVED_GUMMEI    8   /* maxnoofRATs: 8 */
 | 
						||
#define OGS_MAX_NUM_OF_SERVED_GUAMI     256 /* maxnoofServedGUAMIs: 256 */
 | 
						||
#define OGS_MAX_NUM_OF_SUPPORTED_TA     256 /* maxnoofTACs: 256 */
 | 
						||
 | 
						||
/*
 | 
						||
 * <December 3, 2023>
 | 
						||
 * If I set it to 1024, the AMF crashes in the 'meson test -v registration'.
 | 
						||
 * So for now, I will use 512. Once I figure out the cause of this problem,
 | 
						||
 * I will try 1024.
 | 
						||
 *
 | 
						||
 * <December 4, 2023>
 | 
						||
 * After increasing the delay in test/app/5gc-init.c from 300ms to 500ms,
 | 
						||
 * the problem has been resolved. It seems that as the context memory increases,
 | 
						||
 * it takes time for the AMF execution to be completed."
 | 
						||
 */
 | 
						||
#define OGS_MAX_NUM_OF_SLICE_SUPPORT    1024 /* maxnoofSliceItems: 1024 */
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_PLMN_PER_MME     32  /* maxnoofPLMNs(MME): 32 */
 | 
						||
#define OGS_MAX_NUM_OF_PLMN             12  /* maxnoofPLMNs(AMF): 12 */
 | 
						||
#define OGS_MAX_NUM_OF_BPLMN            OGS_MAX_NUM_OF_PLMN
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_TAI              16
 | 
						||
#define OGS_MAX_NUM_OF_SLICE            8
 | 
						||
 | 
						||
#define OGS_NEXT_ID(__id, __min, __max) \
 | 
						||
    ((__id) = ((__id) == (__max) ? (__min) : ((__id) + 1)))
 | 
						||
#define OGS_COMPARE_ID(__id1, __id2, __max) \
 | 
						||
    ((__id2) > (__id1) ? ((__id2) - (__id1) < ((__max)-1) ? -1 : 1) : \
 | 
						||
     (__id1) > (__id2) ? ((__id1) - (__id2) < ((__max)-1) ? 1 : -1) : 0)
 | 
						||
 | 
						||
#define OGS_TIME_TO_BCD(x) \
 | 
						||
    (((((x) % 10) << 4) & 0xf0) | (((x) / 10) & 0x0f))
 | 
						||
 | 
						||
#define OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED 0
 | 
						||
#define OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED 0
 | 
						||
 | 
						||
#define OGS_ACCESS_TYPE_3GPP 1
 | 
						||
#define OGS_ACCESS_TYPE_NON_3GPP 2
 | 
						||
#define OGS_ACCESS_TYPE_BOTH_3GPP_AND_NON_3GPP 3
 | 
						||
 | 
						||
#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                */
 | 
						||
typedef struct ogs_plmn_id_s {
 | 
						||
ED2(uint8_t mcc2:4;,
 | 
						||
    uint8_t mcc1:4;)
 | 
						||
ED2(uint8_t mnc1:4;,
 | 
						||
    uint8_t mcc3:4;)
 | 
						||
ED2(uint8_t mnc3:4;,
 | 
						||
    uint8_t mnc2:4;)
 | 
						||
} __attribute__ ((packed)) ogs_plmn_id_t;
 | 
						||
 | 
						||
uint32_t ogs_plmn_id_hexdump(void *plmn_id);
 | 
						||
 | 
						||
uint16_t ogs_plmn_id_mcc(ogs_plmn_id_t *plmn_id);
 | 
						||
uint16_t ogs_plmn_id_mnc(ogs_plmn_id_t *plmn_id);
 | 
						||
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_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 {
 | 
						||
ED2(uint8_t mcc2:4;,
 | 
						||
    uint8_t mcc1:4;)
 | 
						||
ED2(uint8_t mnc3:4;,
 | 
						||
    uint8_t mcc3:4;)
 | 
						||
ED2(uint8_t mnc2:4;,
 | 
						||
    uint8_t mnc1:4;)
 | 
						||
} __attribute__ ((packed)) ogs_nas_plmn_id_t;
 | 
						||
 | 
						||
void *ogs_nas_from_plmn_id(
 | 
						||
        ogs_nas_plmn_id_t *ogs_nas_plmn_id, ogs_plmn_id_t *plmn_id);
 | 
						||
void *ogs_nas_to_plmn_id(
 | 
						||
        ogs_plmn_id_t *plmn_id, ogs_nas_plmn_id_t *ogs_nas_plmn_id);
 | 
						||
 | 
						||
/************************************
 | 
						||
 * AMF_ID Structure                 */
 | 
						||
typedef struct ogs_amf_id_s {
 | 
						||
    uint8_t region;
 | 
						||
    uint8_t set1;
 | 
						||
ED2(uint8_t set2:2;,
 | 
						||
    uint8_t pointer:6;)
 | 
						||
} __attribute__ ((packed)) ogs_amf_id_t;
 | 
						||
 | 
						||
typedef struct ogs_guami_s {
 | 
						||
    ogs_plmn_id_t plmn_id;
 | 
						||
    ogs_amf_id_t amf_id;
 | 
						||
} ogs_guami_t;
 | 
						||
 | 
						||
uint32_t ogs_amf_id_hexdump(ogs_amf_id_t *amf_id);
 | 
						||
 | 
						||
ogs_amf_id_t *ogs_amf_id_from_string(ogs_amf_id_t *amf_id, const char *hex);
 | 
						||
char *ogs_amf_id_to_string(ogs_amf_id_t *amf_id);
 | 
						||
 | 
						||
uint8_t ogs_amf_region_id(ogs_amf_id_t *amf_id);
 | 
						||
uint16_t ogs_amf_set_id(ogs_amf_id_t *amf_id);
 | 
						||
uint8_t ogs_amf_pointer(ogs_amf_id_t *amf_id);
 | 
						||
 | 
						||
ogs_amf_id_t *ogs_amf_id_build(ogs_amf_id_t *amf_id,
 | 
						||
        uint8_t region, uint16_t set, uint8_t pointer);
 | 
						||
 | 
						||
/************************************
 | 
						||
 * 9.11.3.4 5GS mobile identity
 | 
						||
 * - Protection Scheme */
 | 
						||
#define OGS_PROTECTION_SCHEME_NULL 0
 | 
						||
#define OGS_PROTECTION_SCHEME_PROFILE_A 1
 | 
						||
#define OGS_PROTECTION_SCHEME_PROFILE_B 2
 | 
						||
 | 
						||
/************************************
 | 
						||
 * SUPI/GPSI                       */
 | 
						||
#define OGS_ID_SUPI_TYPE_IMSI "imsi"
 | 
						||
#define OGS_ID_GPSI_TYPE_MSISDN "msisdn"
 | 
						||
#define OGS_ID_SUPI_TYPE_IMEISV "imeisv"
 | 
						||
char *ogs_id_get_type(const char *str);
 | 
						||
char *ogs_id_get_value(const char *str);
 | 
						||
 | 
						||
/************************************
 | 
						||
 * TAI Structure                    */
 | 
						||
typedef struct ogs_eps_tai_s {
 | 
						||
    ogs_plmn_id_t plmn_id;
 | 
						||
    uint16_t tac;
 | 
						||
} __attribute__ ((packed)) ogs_eps_tai_t;
 | 
						||
 | 
						||
typedef struct ogs_5gs_tai_s {
 | 
						||
    ogs_plmn_id_t plmn_id;
 | 
						||
    ogs_uint24_t tac;
 | 
						||
} __attribute__ ((packed)) ogs_5gs_tai_t;
 | 
						||
 | 
						||
typedef struct ogs_e_cgi_s {
 | 
						||
    ogs_plmn_id_t plmn_id;
 | 
						||
    uint32_t cell_id; /* 28 bit */
 | 
						||
} __attribute__ ((packed)) ogs_e_cgi_t;
 | 
						||
 | 
						||
typedef struct ogs_nr_cgi_s {
 | 
						||
    ogs_plmn_id_t plmn_id;
 | 
						||
    uint64_t cell_id; /* 36 bit */
 | 
						||
} __attribute__ ((packed)) ogs_nr_cgi_t;
 | 
						||
 | 
						||
/************************************
 | 
						||
 * S-NSSAI Structure                */
 | 
						||
#define OGS_S_NSSAI_NO_SD_VALUE     0xffffff
 | 
						||
typedef struct ogs_s_nssai_s {
 | 
						||
    uint8_t sst;
 | 
						||
    ogs_uint24_t sd;
 | 
						||
} __attribute__ ((packed)) ogs_s_nssai_t;
 | 
						||
 | 
						||
char *ogs_s_nssai_sd_to_string(ogs_uint24_t sd);
 | 
						||
ogs_uint24_t ogs_s_nssai_sd_from_string(const char *hex);
 | 
						||
 | 
						||
/**************************************************
 | 
						||
 * Common Structure
 | 
						||
 * S1AP : 9.2.2.1 Transport Layer Address, See 36.414
 | 
						||
 * GTP : 8.22 Fully Qualified TEID (F-TEID) */
 | 
						||
#define OGS_IPV4_LEN                        4
 | 
						||
#define OGS_IPV6_LEN                        16
 | 
						||
#define OGS_IPV6_DEFAULT_PREFIX_LEN         64
 | 
						||
#define OGS_IPV6_128_PREFIX_LEN             128
 | 
						||
#define OGS_IPV4V6_LEN                      20
 | 
						||
typedef struct ogs_ip_s {
 | 
						||
    uint32_t addr;
 | 
						||
    uint8_t addr6[OGS_IPV6_LEN];
 | 
						||
    uint32_t len;
 | 
						||
ED3(uint8_t ipv4:1;,
 | 
						||
    uint8_t ipv6:1;,
 | 
						||
    uint8_t reserved:6;)
 | 
						||
} ogs_ip_t;
 | 
						||
 | 
						||
int ogs_ip_to_sockaddr(ogs_ip_t *ip, uint16_t port, ogs_sockaddr_t **list);
 | 
						||
int ogs_sockaddr_to_ip(
 | 
						||
        ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, ogs_ip_t *ip);
 | 
						||
 | 
						||
char *ogs_ipv4_to_string(uint32_t addr);
 | 
						||
char *ogs_ipv6addr_to_string(uint8_t *addr6);
 | 
						||
char *ogs_ipv6prefix_to_string(uint8_t *addr6, uint8_t prefixlen);
 | 
						||
int ogs_ipv4_from_string(uint32_t *addr, char *string);
 | 
						||
int ogs_ipv6addr_from_string(uint8_t *addr6, char *string);
 | 
						||
int ogs_ipv6prefix_from_string(
 | 
						||
        uint8_t *addr6, uint8_t *prefixlen, char *string);
 | 
						||
 | 
						||
/**************************************************
 | 
						||
 * GTPv1-C: TS 29.060 7.7.27 End User Address (EUA) */
 | 
						||
#define OGS_PDP_EUA_ORG_ETSI 0
 | 
						||
#define OGS_PDP_EUA_ORG_IETF 1
 | 
						||
#define OGS_PDP_EUA_ETSI_PPP 1
 | 
						||
#define OGS_PDP_EUA_IETF_IPV4 0x21
 | 
						||
#define OGS_PDP_EUA_IETF_IPV6 0x57
 | 
						||
#define OGS_PDP_EUA_IETF_IPV4V6 0x8D
 | 
						||
typedef struct ogs_eua_s {
 | 
						||
ED2(uint8_t spare:4;,
 | 
						||
    uint8_t organization:4;)
 | 
						||
    uint8_t type;
 | 
						||
    union {
 | 
						||
        /* PDU_SESSION_TYPE_IPV4 */
 | 
						||
        uint32_t addr;
 | 
						||
 | 
						||
        /* PDU_SESSION_TYPE_IPV6 */
 | 
						||
        uint8_t addr6[OGS_IPV6_LEN];
 | 
						||
 | 
						||
        /* PDU_SESSION_TYPE_IPV4V6 */
 | 
						||
        struct {
 | 
						||
            uint32_t addr;
 | 
						||
            uint8_t addr6[OGS_IPV6_LEN];
 | 
						||
        } __attribute__ ((packed)) both;
 | 
						||
    };
 | 
						||
} __attribute__ ((packed)) ogs_eua_t;
 | 
						||
 | 
						||
/**************************************************
 | 
						||
 * GTPv2-C: TS 29.274 8.14 PDN Address Allocation (PAA) */
 | 
						||
#define OGS_PAA_IPV4_LEN                                5
 | 
						||
#define OGS_PAA_IPV6_LEN                                18
 | 
						||
#define OGS_PAA_IPV4V6_LEN                              22
 | 
						||
typedef struct ogs_paa_s {
 | 
						||
ED2(uint8_t spare:5;,
 | 
						||
/* 8.34 PDN Type  */
 | 
						||
#define OGS_PDU_SESSION_TYPE_IS_VALID(x) \
 | 
						||
        ((x) == OGS_PDU_SESSION_TYPE_IPV4 || \
 | 
						||
         (x) == OGS_PDU_SESSION_TYPE_IPV6 || \
 | 
						||
         (x) == OGS_PDU_SESSION_TYPE_IPV4V6) \
 | 
						||
 | 
						||
    uint8_t session_type:3;)
 | 
						||
    union {
 | 
						||
        /* PDU_SESSION_TYPE_IPV4 */
 | 
						||
        uint32_t addr;
 | 
						||
 | 
						||
        /* PDU_SESSION_TYPE_IPV6 */
 | 
						||
        struct {
 | 
						||
            /* the IPv6 Prefix Length */
 | 
						||
            uint8_t len;
 | 
						||
            /* IPv6 Prefix and Interface Identifier */
 | 
						||
            uint8_t addr6[OGS_IPV6_LEN];
 | 
						||
        };
 | 
						||
 | 
						||
        /* PDU_SESSION_TYPE_IPV4V6 */
 | 
						||
        struct {
 | 
						||
            struct {
 | 
						||
                /* the IPv6 Prefix Length */
 | 
						||
                uint8_t len;
 | 
						||
                /* IPv6 Prefix and Interface Identifier */
 | 
						||
                uint8_t addr6[OGS_IPV6_LEN];
 | 
						||
            };
 | 
						||
            uint32_t addr;
 | 
						||
        } __attribute__ ((packed)) both;
 | 
						||
    };
 | 
						||
} __attribute__ ((packed)) ogs_paa_t;
 | 
						||
 | 
						||
#define MAX_BIT_RATE 10000000000UL
 | 
						||
 | 
						||
typedef struct ogs_bitrate_s {
 | 
						||
    uint64_t downlink;        /* bits per seconds */
 | 
						||
    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 {
 | 
						||
#define OGS_QOS_INDEX_1                                       1
 | 
						||
#define OGS_QOS_INDEX_2                                       2
 | 
						||
#define OGS_QOS_INDEX_5                                       5
 | 
						||
    uint8_t         index;
 | 
						||
 | 
						||
    struct {
 | 
						||
    /* Values 1 to 8 should only be assigned for services that are
 | 
						||
     * authorized to receive prioritized treatment within an operator domain.
 | 
						||
     * Values 9 to 15 may be assigned to resources that are authorized
 | 
						||
     * by the home network and thus applicable when a UE is roaming. */
 | 
						||
        uint8_t     priority_level;
 | 
						||
/*
 | 
						||
 * Ch 7.3.40 Allocation-Retenion-Proirty in TS 29.272 V15.9.0
 | 
						||
 *
 | 
						||
 * If the Pre-emption-Capability AVP is not present in the
 | 
						||
 * Allocation-Retention-Priority AVP, the default value shall be
 | 
						||
 * PRE-EMPTION_CAPABILITY_DISABLED (1).
 | 
						||
 *
 | 
						||
 * If the Pre-emption-Vulnerability AVP is not present in the
 | 
						||
 * Allocation-Retention-Priority AVP, the default value shall be
 | 
						||
 * PRE-EMPTION_VULNERABILITY_ENABLED (0).
 | 
						||
 *
 | 
						||
 * However, to easily set up VoLTE service,
 | 
						||
 * enable Pre-emption Capability/Vulnerablility
 | 
						||
 * in Default Bearer
 | 
						||
 */
 | 
						||
#define OGS_EPC_PRE_EMPTION_DISABLED                        1
 | 
						||
#define OGS_EPC_PRE_EMPTION_ENABLED                         0
 | 
						||
 | 
						||
#define OGS_5GC_PRE_EMPTION_DISABLED                        1
 | 
						||
#define OGS_5GC_PRE_EMPTION_ENABLED                         2
 | 
						||
        uint8_t     pre_emption_capability;
 | 
						||
        uint8_t     pre_emption_vulnerability;
 | 
						||
    } arp;
 | 
						||
 | 
						||
    ogs_bitrate_t   mbr;  /* Maxmimum Bit Rate (MBR) */
 | 
						||
    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
 | 
						||
#define OGS_FLOW_UPLINK_ONLY      2
 | 
						||
typedef struct ogs_flow_s {
 | 
						||
    uint8_t direction;
 | 
						||
    char *description;
 | 
						||
} ogs_flow_t;
 | 
						||
 | 
						||
#define OGS_FLOW_FREE(__fLOW) \
 | 
						||
    do { \
 | 
						||
        if ((__fLOW)->description) { \
 | 
						||
            ogs_free((__fLOW)->description); \
 | 
						||
        } \
 | 
						||
        else \
 | 
						||
            ogs_assert_if_reached(); \
 | 
						||
    } while(0)
 | 
						||
 | 
						||
/**********************************
 | 
						||
 * PCC Rule Structure            */
 | 
						||
typedef struct ogs_pcc_rule_s {
 | 
						||
#define OGS_PCC_RULE_TYPE_INSTALL               1
 | 
						||
#define OGS_PCC_RULE_TYPE_REMOVE                2
 | 
						||
    uint8_t type;
 | 
						||
 | 
						||
    char *id;   /* 5GC */
 | 
						||
    char *name; /* EPC */
 | 
						||
 | 
						||
    ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE];
 | 
						||
    int num_of_flow;
 | 
						||
 | 
						||
    int flow_status;
 | 
						||
    uint32_t precedence;
 | 
						||
 | 
						||
    ogs_qos_t  qos;
 | 
						||
} ogs_pcc_rule_t;
 | 
						||
 | 
						||
#define OGS_STORE_PCC_RULE(__dST, __sRC) \
 | 
						||
    do { \
 | 
						||
        int __iNDEX; \
 | 
						||
        ogs_assert((__sRC) != NULL); \
 | 
						||
        ogs_assert((__dST) != NULL); \
 | 
						||
        OGS_PCC_RULE_FREE(__dST); \
 | 
						||
        (__dST)->type = (__sRC)->type; \
 | 
						||
        if ((__sRC)->name) { \
 | 
						||
            (__dST)->name = ogs_strdup((__sRC)->name); \
 | 
						||
            ogs_assert((__dST)->name); \
 | 
						||
        } \
 | 
						||
        if ((__sRC)->id) { \
 | 
						||
            (__dST)->id = ogs_strdup((__sRC)->id); \
 | 
						||
            ogs_assert((__dST)->id); \
 | 
						||
        } \
 | 
						||
        for (__iNDEX = 0; __iNDEX < (__sRC)->num_of_flow; __iNDEX++) { \
 | 
						||
            (__dST)->flow[__iNDEX].direction = \
 | 
						||
                (__sRC)->flow[__iNDEX].direction; \
 | 
						||
            (__dST)->flow[__iNDEX].description = \
 | 
						||
                ogs_strdup((__sRC)->flow[__iNDEX].description);  \
 | 
						||
            ogs_assert((__dST)->flow[__iNDEX].description); \
 | 
						||
        } \
 | 
						||
        (__dST)->num_of_flow = (__sRC)->num_of_flow; \
 | 
						||
        (__dST)->flow_status = (__sRC)->flow_status; \
 | 
						||
        (__dST)->precedence = (__sRC)->precedence; \
 | 
						||
        memcpy(&(__dST)->qos, &(__sRC)->qos, sizeof(ogs_qos_t)); \
 | 
						||
    } while(0)
 | 
						||
 | 
						||
#define OGS_PCC_RULE_FREE(__pCCrULE) \
 | 
						||
    do { \
 | 
						||
        int __pCCrULE_iNDEX; \
 | 
						||
        ogs_assert((__pCCrULE) != NULL); \
 | 
						||
        if ((__pCCrULE)->id) \
 | 
						||
            ogs_free((__pCCrULE)->id); \
 | 
						||
        if ((__pCCrULE)->name) \
 | 
						||
            ogs_free((__pCCrULE)->name); \
 | 
						||
        for (__pCCrULE_iNDEX = 0; \
 | 
						||
            __pCCrULE_iNDEX < (__pCCrULE)->num_of_flow; __pCCrULE_iNDEX++) { \
 | 
						||
            OGS_FLOW_FREE(&((__pCCrULE)->flow[__pCCrULE_iNDEX])); \
 | 
						||
        } \
 | 
						||
        memset((__pCCrULE), 0, sizeof(ogs_pcc_rule_t)); \
 | 
						||
    } while(0)
 | 
						||
 | 
						||
/**********************************
 | 
						||
 * PDN Structure                 */
 | 
						||
typedef struct ogs_session_s {
 | 
						||
    char *name;
 | 
						||
 | 
						||
    uint32_t context_identifier; /* EPC */
 | 
						||
    bool default_dnn_indicator; /* 5GC */
 | 
						||
 | 
						||
    uint8_t charging_characteristics[OGS_CHRGCHARS_LEN];
 | 
						||
    bool charging_characteristics_presence;
 | 
						||
 | 
						||
#define OGS_PDU_SESSION_TYPE_IPV4                   1
 | 
						||
#define OGS_PDU_SESSION_TYPE_IPV6                   2
 | 
						||
#define OGS_PDU_SESSION_TYPE_IPV4V6                 3
 | 
						||
#define OGS_PDU_SESSION_TYPE_UNSTRUCTURED           4
 | 
						||
#define OGS_PDU_SESSION_TYPE_ETHERNET               5
 | 
						||
 | 
						||
#define OGS_PDU_SESSION_TYPE_TO_DIAMETER(x)         ((x)-1)
 | 
						||
#define OGS_PDU_SESSION_TYPE_FROM_DIAMETER(x)       ((x)+1)
 | 
						||
    uint8_t session_type;
 | 
						||
 | 
						||
#define OGS_SSC_MODE_1                              1
 | 
						||
#define OGS_SSC_MODE_2                              2
 | 
						||
#define OGS_SSC_MODE_3                              3
 | 
						||
    uint8_t ssc_mode;
 | 
						||
 | 
						||
    ogs_qos_t qos;
 | 
						||
    ogs_bitrate_t ambr; /* APN-AMBR */
 | 
						||
 | 
						||
    ogs_paa_t paa;
 | 
						||
    ogs_ip_t ue_ip;
 | 
						||
    char **ipv4_framed_routes;
 | 
						||
    char **ipv6_framed_routes;
 | 
						||
    ogs_ip_t smf_ip;
 | 
						||
} ogs_session_t;
 | 
						||
 | 
						||
int ogs_fqdn_build(char *dst, const char *src, int len);
 | 
						||
int ogs_fqdn_parse(char *dst, const char *src, int len);
 | 
						||
 | 
						||
/**************************************************
 | 
						||
 * Protocol Configuration Options Structure
 | 
						||
 * 8.13 Protocol Configuration Options (PCO)
 | 
						||
 * 10.5.6.3 Protocol configuration options in 3GPP TS 24.008
 | 
						||
 * RFC 3232 [103]
 | 
						||
 * RFC 1661 [102] */
 | 
						||
#define OGS_PCO_PPP_FOR_USE_WITH_IP_PDP_TYPE_OR_IP_PDN_TYPE 0
 | 
						||
 | 
						||
#define OGS_PCO_ID_INTERNET_PROTOCOL_CONTROL_PROTOCOL           0x8021
 | 
						||
#define OGS_PCO_ID_PASSWORD_AUTHENTICATION_PROTOCOL             0xc023
 | 
						||
#define OGS_PCO_ID_CHALLENGE_HANDSHAKE_AUTHENTICATION_PROTOCOL  0xc223
 | 
						||
#define OGS_PCO_ID_P_CSCF_IPV6_ADDRESS_REQUEST                  0x0001
 | 
						||
#define OGS_PCO_ID_DNS_SERVER_IPV6_ADDRESS_REQUEST              0x0003
 | 
						||
#define OGS_PCO_ID_MS_SUPPORTS_BCM                              0x0005
 | 
						||
#define OGS_PCO_ID_IP_ADDRESS_ALLOCATION_VIA_NAS_SIGNALLING     0x000a
 | 
						||
#define OGS_PCO_ID_P_CSCF_IPV4_ADDRESS_REQUEST                  0x000c
 | 
						||
#define OGS_PCO_ID_DNS_SERVER_IPV4_ADDRESS_REQUEST              0x000d
 | 
						||
#define OGS_PCO_ID_IPV4_LINK_MTU_REQUEST                        0x0010
 | 
						||
#define OGS_PCO_ID_MS_SUPPORT_LOCAL_ADDR_TFT_INDICATOR          0x0011
 | 
						||
#define OGS_PCO_ID_P_CSCF_RE_SELECTION_SUPPORT                  0x0012
 | 
						||
 | 
						||
enum ogs_pco_ipcp_options {
 | 
						||
    OGS_IPCP_OPT_IPADDR = 3,
 | 
						||
    OGS_IPCP_OPT_PRIMARY_DNS = 129,
 | 
						||
    OGS_IPCP_OPT_SECONDARY_DNS = 131,
 | 
						||
};
 | 
						||
 | 
						||
typedef struct ogs_pco_ipcp_options_s {
 | 
						||
    uint8_t type;
 | 
						||
    uint8_t len;
 | 
						||
    uint32_t addr;
 | 
						||
} __attribute__ ((packed)) ogs_pco_ipcp_options_t;
 | 
						||
 | 
						||
#define OGS_PCO_MAX_NUM_OF_IPCP_OPTIONS 4
 | 
						||
typedef struct ogs_pco_ipcp_s {
 | 
						||
    uint8_t code;
 | 
						||
    uint8_t identifier;
 | 
						||
    uint16_t len;
 | 
						||
    ogs_pco_ipcp_options_t options[OGS_PCO_MAX_NUM_OF_IPCP_OPTIONS];
 | 
						||
} __attribute__ ((packed)) ogs_pco_ipcp_t;
 | 
						||
 | 
						||
typedef struct ogs_pco_pap_s {
 | 
						||
    uint8_t code;
 | 
						||
    uint8_t identifier;
 | 
						||
    uint16_t len;
 | 
						||
    uint8_t welcome_len;
 | 
						||
    char welcome[255];
 | 
						||
} __attribute__ ((packed)) ogs_pco_pap_t;
 | 
						||
 | 
						||
typedef struct ogs_pco_chap_s {
 | 
						||
    uint8_t code;
 | 
						||
    uint8_t identifier;
 | 
						||
    uint16_t len;
 | 
						||
} __attribute__ ((packed)) ogs_pco_chap_t;
 | 
						||
 | 
						||
typedef struct ogs_pco_id_s {
 | 
						||
    uint16_t id;
 | 
						||
    uint8_t len;
 | 
						||
    void *data;
 | 
						||
} ogs_pco_id_t;
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID    16
 | 
						||
typedef struct ogs_pco_s {
 | 
						||
ED3(uint8_t ext:1;,
 | 
						||
    uint8_t spare:4;,
 | 
						||
    uint8_t configuration_protocol:3;)
 | 
						||
    uint8_t num_of_id;
 | 
						||
    ogs_pco_id_t ids[OGS_MAX_NUM_OF_PROTOCOL_OR_CONTAINER_ID];
 | 
						||
} ogs_pco_t;
 | 
						||
 | 
						||
int ogs_pco_parse(ogs_pco_t *pco, unsigned char *data, int data_len);
 | 
						||
int ogs_pco_build(unsigned char *data, int data_len, ogs_pco_t *pco);
 | 
						||
 | 
						||
/*
 | 
						||
 * PFCP Specification
 | 
						||
 *
 | 
						||
 * TS29.244, Ch 8.2.82 User Plane IP Resource Information
 | 
						||
 *
 | 
						||
 * The following flags are coded within Octet 5:
 | 
						||
 * - Bit 1 – V4: If this bit is set to "1", then the IPv4 address field
 | 
						||
 *   shall be present, otherwise the IPv4 address field shall not be present.
 | 
						||
 * - Bit 2 – V6: If this bit is set to "1", then the IPv6 address field
 | 
						||
 *   shall be present, otherwise the IPv6 address field shall not be present.
 | 
						||
 * - Bit 3-5 – TEID Range Indication (TEIDRI): the value of this field
 | 
						||
 *   indicates the number of bits in the most significant octet of a TEID
 | 
						||
 *   that are used to partition the TEID range,
 | 
						||
 *   e.g. if this field is set to "4", then the first 4 bits in the TEID
 | 
						||
 *   are used to partition the TEID range.
 | 
						||
 * - Bit 6 – Associated Network Instance (ASSONI): if this bit is set to "1",
 | 
						||
 *   then the Network Instance field shall be present, otherwise the Network
 | 
						||
 *   Instance field shall not be present.
 | 
						||
 * - Bit 7 – Associated Source Interface (ASSOSI): if this bit is set to "1",
 | 
						||
 *   then the Source Interface field shall be present,
 | 
						||
 *   otherwise the Source Interface field shall not be present.
 | 
						||
 * - Bit 8: Spare, for future use and set to 0.
 | 
						||
 *
 | 
						||
 * At least one of the V4 and V6 flags shall be set to "1",
 | 
						||
 * and both may be set to "1".
 | 
						||
 *
 | 
						||
 * If both the ASSONI and ASSOSI flags are set to "0", this shall indicate
 | 
						||
 * that the User Plane IP Resource Information provided can be used
 | 
						||
 * by CP function for any Network Instance and any Source Interface
 | 
						||
 * of GTP-U user plane in the UP function.  Octet 6 (TEID Range) shall be
 | 
						||
 * present if the TEID Range Indication is not set to zero and
 | 
						||
 * shall contain a value of the bits which are used to partition the TEID range.
 | 
						||
 * E.g. if the TEID Range Indication is set to "4", then Octet 6 shall be
 | 
						||
 * one of values between 0 and 15. When TEID Range Indication is set to zero,
 | 
						||
 * the Octet 6 shall not be present, the TEID is not partitioned,
 | 
						||
 * i.e. all TEID values are available for use by the CP function.
 | 
						||
 *
 | 
						||
 * Octets "m to (m+3)" and/or "p to (p+15)" (IPv4 address / IPv6 address fields)
 | 
						||
 * , if present, shall contain the respective IP address values.
 | 
						||
 *
 | 
						||
 * Octets "k to l", if present, shall contain a Network Instance value
 | 
						||
 * as encoded in octet "5 to n+4" of the Figure 8.2.4-1 in clause 8.2.4,
 | 
						||
 * identifying a Network Instance with which the IP address or TEID Range
 | 
						||
 * is associated.
 | 
						||
 *
 | 
						||
 * Octet r, if present, shall contain a Source Interface value as encoded
 | 
						||
 * in octet 5 of the Figure 8.2.2-1 in clause 8.2.2,
 | 
						||
 * identifying the Source Interface with which the IP address or TEID Range
 | 
						||
 * is associated.
 | 
						||
 */
 | 
						||
 | 
						||
/* Flags(1) + TEID Range(1) + IPV4(4) + IPV6(16) + Source Interface(1) = 23 */
 | 
						||
#define OGS_MAX_USER_PLANE_IP_RESOURCE_INFO_LEN \
 | 
						||
    (23 + (OGS_MAX_APN_LEN+1))
 | 
						||
typedef struct ogs_user_plane_ip_resource_info_s {
 | 
						||
    union {
 | 
						||
        struct {
 | 
						||
ED6(uint8_t     spare:1;,
 | 
						||
    uint8_t     assosi:1;,
 | 
						||
    uint8_t     assoni:1;,
 | 
						||
    uint8_t     teidri:3;,
 | 
						||
    uint8_t     v6:1;,
 | 
						||
    uint8_t     v4:1;)
 | 
						||
        };
 | 
						||
        uint8_t flags;
 | 
						||
    };
 | 
						||
 | 
						||
    /*
 | 
						||
     * OGS_PFCP-GTPU-TEID   = INDEX              | TEID_RANGE
 | 
						||
     * INDEX                = OGS_PFCP-GTPU-TEID & ~TEID_RANGE
 | 
						||
     */
 | 
						||
#define OGS_PFCP_GTPU_TEID_TO_INDEX(__tEID, __iND, __rANGE) \
 | 
						||
    (__tEID & ~(__rANGE << (32 - __iND)))
 | 
						||
#define OGS_PFCP_GTPU_INDEX_TO_TEID(__iNDEX, __iND, __rANGE) \
 | 
						||
    (__iNDEX | (__rANGE << (32 - __iND)))
 | 
						||
    uint8_t     teid_range;
 | 
						||
    uint32_t    addr;
 | 
						||
    uint8_t     addr6[OGS_IPV6_LEN];
 | 
						||
    char        network_instance[OGS_MAX_APN_LEN+1];
 | 
						||
    uint8_t     source_interface;
 | 
						||
} __attribute__ ((packed)) ogs_user_plane_ip_resource_info_t;
 | 
						||
 | 
						||
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);
 | 
						||
int ogs_user_plane_ip_resource_info_to_sockaddr(
 | 
						||
    ogs_user_plane_ip_resource_info_t *info,
 | 
						||
    ogs_sockaddr_t **addr, ogs_sockaddr_t **addr6);
 | 
						||
 | 
						||
typedef struct ogs_slice_data_s {
 | 
						||
    ogs_s_nssai_t s_nssai;
 | 
						||
    bool default_indicator;
 | 
						||
 | 
						||
    uint32_t context_identifier; /* EPC for checking default APN */
 | 
						||
 | 
						||
#define OGS_ALL_APN_CONFIGURATIONS_INCLUDED 0
 | 
						||
#define OGS_MODIFIED_ADDED_APN_CONFIGURATIONS_INCLUDED 1
 | 
						||
    uint32_t all_apn_config_inc;
 | 
						||
 | 
						||
    int num_of_session;
 | 
						||
    ogs_session_t session[OGS_MAX_NUM_OF_SESS];
 | 
						||
} ogs_slice_data_t;
 | 
						||
 | 
						||
ogs_slice_data_t *ogs_slice_find_by_s_nssai(
 | 
						||
        ogs_slice_data_t *slice_data, int num_of_slice_data,
 | 
						||
        ogs_s_nssai_t *s_nssai);
 | 
						||
 | 
						||
typedef struct ogs_subscription_data_s {
 | 
						||
#define OGS_ACCESS_RESTRICTION_UTRAN_NOT_ALLOWED                (1)
 | 
						||
#define OGS_ACCESS_RESTRICTION_GERAN_NOT_ALLOWED                (1<<1)
 | 
						||
#define OGS_ACCESS_RESTRICTION_GAN_NOT_ALLOWED                  (1<<2)
 | 
						||
#define OGS_ACCESS_RESTRICTION_I_HSPA_EVOLUTION_NOT_ALLOWED     (1<<3)
 | 
						||
#define OGS_ACCESS_RESTRICTION_WB_E_UTRAN_NOT_ALLOWED           (1<<4)
 | 
						||
#define OGS_ACCESS_RESTRICTION_HO_TO_NON_3GPP_ACCESS_NOT_ALLOWED (1<<5)
 | 
						||
#define OGS_ACCESS_RESTRICTION_NB_IOT_NOT_ALLOWED               (1<<6)
 | 
						||
    uint32_t                access_restriction_data;
 | 
						||
#define OGS_SUBSCRIBER_STATUS_SERVICE_GRANTED                   0
 | 
						||
#define OGS_SUBSCRIBER_STATUS_OPERATOR_DETERMINED_BARRING       1
 | 
						||
    uint32_t                subscriber_status;
 | 
						||
#define OGS_OP_DET_BARRING_ALL_PS_BARRED                                            (1<<0)
 | 
						||
#define OGS_OP_DET_BARRING_ROAM_ACC_HPLMN_AP_BARRED                                 (1<<1)
 | 
						||
#define OGS_OP_DET_BARRING_ROAM_ACC_VPLMN_AP_BARRED                                 (1<<2)
 | 
						||
#define OGS_OP_DET_BARRING_ALL_OUT_CALLS                                            (1<<3)
 | 
						||
#define OGS_OP_DET_BARRING_ALL_OUT_INT_CALLS                                        (1<<4)
 | 
						||
#define OGS_OP_DET_BARRING_ALL_OUT_INT_CALLS_EXCL_HPLMN_COUNTRY                     (1<<5)
 | 
						||
#define OGS_OP_DET_BARRING_ALL_OUT_INTERZONE_CALLS                                  (1<<6)
 | 
						||
#define OGS_OP_DET_BARRING_ALL_OUT_INTERZONE_CALLS_EXCL_HPLMN_COUNTRY               (1<<7)
 | 
						||
#define OGS_OPD_ETEBARRING_OUT_INT_CALLS_EXCL_EXCL_HPLMN_COUNTRY_AND_INTERZONE_CALLS (1<<8)
 | 
						||
    uint32_t operator_determined_barring; /* 3GPP TS 29.272 7.3.30 */
 | 
						||
#define OGS_NETWORK_ACCESS_MODE_PACKET_AND_CIRCUIT              0
 | 
						||
#define OGS_NETWORK_ACCESS_MODE_RESERVED                        1
 | 
						||
#define OGS_NETWORK_ACCESS_MODE_ONLY_PACKET                     2
 | 
						||
    uint32_t                network_access_mode;
 | 
						||
 | 
						||
    ogs_bitrate_t           ambr;                           /* UE-AMBR */
 | 
						||
 | 
						||
#define OGS_RAU_TAU_DEFAULT_TIME                (12*60)     /* 12 min */
 | 
						||
    uint32_t                subscribed_rau_tau_timer;       /* unit : seconds */
 | 
						||
 | 
						||
    int num_of_slice;
 | 
						||
    ogs_slice_data_t slice[OGS_MAX_NUM_OF_SLICE];
 | 
						||
 | 
						||
    char *imsi;
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_MSISDN                                   2
 | 
						||
    int num_of_msisdn;
 | 
						||
    struct {
 | 
						||
        uint8_t buf[OGS_MAX_MSISDN_LEN];
 | 
						||
        int len;
 | 
						||
        char bcd[OGS_MAX_MSISDN_BCD_LEN+1];
 | 
						||
    } msisdn[OGS_MAX_NUM_OF_MSISDN];
 | 
						||
 | 
						||
    char *mme_host;
 | 
						||
    char *mme_realm;
 | 
						||
    bool purge_flag;
 | 
						||
} ogs_subscription_data_t;
 | 
						||
 | 
						||
void ogs_subscription_data_free(ogs_subscription_data_t *subscription_data);
 | 
						||
 | 
						||
typedef struct ogs_session_data_s {
 | 
						||
    ogs_session_t session;
 | 
						||
#define OGS_MAX_NUM_OF_PCC_RULE         8   /* Num of PCC Rule */
 | 
						||
    ogs_pcc_rule_t pcc_rule[OGS_MAX_NUM_OF_PCC_RULE];
 | 
						||
    int num_of_pcc_rule;
 | 
						||
} ogs_session_data_t;
 | 
						||
 | 
						||
#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;
 | 
						||
/*
 | 
						||
 * TS29.214
 | 
						||
 * 5.3.12 Flow-Usage AVP
 | 
						||
 *   NO_INFORMATION(0)
 | 
						||
 *   RTCP(1)
 | 
						||
 *   AF_SIGNALLING(2)
 | 
						||
 *
 | 
						||
 * TS29.514
 | 
						||
 * 5.6.3.14 Enumeration: FlowUsage
 | 
						||
 *   NO_INFO : 1
 | 
						||
 *   RTCP : 2
 | 
						||
 *   AF_SIGNALLING : 3
 | 
						||
 *
 | 
						||
 * EPC and 5GC have different values for FlowUsage
 | 
						||
 * At this point, we will use the 5GC value.
 | 
						||
 */
 | 
						||
#define OGS_FLOW_USAGE_NO_INFO          1
 | 
						||
#define OGS_FLOW_USAGE_RTCP             2
 | 
						||
#define OGS_FLOW_USAGE_AF_SIGNALLING    3
 | 
						||
    uint32_t            flow_usage;
 | 
						||
    ogs_flow_t          flow[OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT];
 | 
						||
    int                 num_of_flow;
 | 
						||
} ogs_media_sub_component_t;
 | 
						||
 | 
						||
typedef struct ogs_media_component_s {
 | 
						||
    uint32_t            media_component_number;
 | 
						||
    uint32_t            media_type;
 | 
						||
 | 
						||
    uint64_t            max_requested_bandwidth_dl;
 | 
						||
    uint64_t            max_requested_bandwidth_ul;
 | 
						||
    uint64_t            min_requested_bandwidth_dl;
 | 
						||
    uint64_t            min_requested_bandwidth_ul;
 | 
						||
    uint64_t            rr_bandwidth;
 | 
						||
    uint64_t            rs_bandwidth;
 | 
						||
 | 
						||
    int                 flow_status;
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_MEDIA_SUB_COMPONENT     8
 | 
						||
    ogs_media_sub_component_t sub[OGS_MAX_NUM_OF_MEDIA_SUB_COMPONENT];
 | 
						||
    int                 num_of_sub;
 | 
						||
} ogs_media_component_t;
 | 
						||
 | 
						||
typedef struct ogs_ims_data_s {
 | 
						||
    int num_of_msisdn;
 | 
						||
    struct {
 | 
						||
        uint8_t buf[OGS_MAX_MSISDN_LEN];
 | 
						||
        int len;
 | 
						||
        char bcd[OGS_MAX_MSISDN_BCD_LEN+1];
 | 
						||
    } msisdn[OGS_MAX_NUM_OF_MSISDN];
 | 
						||
 | 
						||
#define OGS_MAX_NUM_OF_MEDIA_COMPONENT 16
 | 
						||
    ogs_media_component_t media_component[OGS_MAX_NUM_OF_MEDIA_COMPONENT];
 | 
						||
    int num_of_media_component;
 | 
						||
} ogs_ims_data_t;
 | 
						||
 | 
						||
void ogs_ims_data_free(ogs_ims_data_t *ims_data);
 | 
						||
 | 
						||
int ogs_pcc_rule_num_of_flow_equal_to_media(
 | 
						||
        ogs_pcc_rule_t *pcc_rule, ogs_media_component_t *media_component);
 | 
						||
int ogs_pcc_rule_install_flow_from_media(
 | 
						||
        ogs_pcc_rule_t *pcc_rule, ogs_media_component_t *media_component);
 | 
						||
int ogs_pcc_rule_update_qos_from_media(
 | 
						||
        ogs_pcc_rule_t *pcc_rule, ogs_media_component_t *media_component);
 | 
						||
 | 
						||
typedef struct ogs_datum_s {
 | 
						||
    unsigned char *data;
 | 
						||
    unsigned int size;
 | 
						||
} ogs_datum_t;
 | 
						||
 | 
						||
typedef struct ogs_port_s {
 | 
						||
    bool presence;
 | 
						||
    uint16_t port;
 | 
						||
} ogs_port_t;
 | 
						||
 | 
						||
#ifdef __cplusplus
 | 
						||
}
 | 
						||
#endif
 | 
						||
 | 
						||
#endif /* OGS_PROTO_TYPES_H */
 |