[SMF] Added User-ID, APP_DNN, S-NSSAI (#1986)

Added User-ID, APP_DNN, S-NSSAI in N4 PFCP Session Establishment Request
This commit is contained in:
Sukchan Lee 2023-01-13 10:28:40 +09:00
parent 92efca1fbf
commit 5128ebc6c6
6 changed files with 280 additions and 13 deletions

View File

@ -686,3 +686,61 @@ int16_t ogs_pfcp_parse_volume_measurement(
return size;
}
int16_t ogs_pfcp_build_user_id(
ogs_tlv_octet_t *octet, ogs_pfcp_user_id_t *user_id,
void *data, int data_len)
{
ogs_pfcp_user_id_t target;
int16_t size = 0;
ogs_assert(user_id);
ogs_assert(octet);
ogs_assert(data);
ogs_assert(data_len);
octet->data = data;
memcpy(&target, user_id, sizeof(ogs_pfcp_user_id_t));
ogs_assert(size + sizeof(target.flags) <= data_len);
memcpy((unsigned char *)octet->data + size,
&target.flags, sizeof(target.flags));
size += sizeof(target.flags);
if (target.imsif) {
ogs_assert(size + sizeof(target.imsi_len) <= data_len);
memcpy((unsigned char *)octet->data + size,
&target.imsi_len, sizeof(target.imsi_len));
size += sizeof(target.imsi_len);
ogs_assert(size + user_id->imsi_len <= data_len);
memcpy((char *)octet->data + size, user_id->imsi, user_id->imsi_len);
size += user_id->imsi_len;
}
if (target.imeif) {
ogs_assert(size + sizeof(target.imeisv_len) <= data_len);
memcpy((unsigned char *)octet->data + size,
&target.imeisv_len, sizeof(target.imeisv_len));
size += sizeof(target.imeisv_len);
ogs_assert(size + user_id->imeisv_len <= data_len);
memcpy((char *)octet->data + size,
user_id->imeisv, user_id->imeisv_len);
size += user_id->imeisv_len;
}
if (target.msisdnf) {
ogs_assert(size + sizeof(target.msisdn_len) <= data_len);
memcpy((unsigned char *)octet->data + size,
&target.msisdn_len, sizeof(target.msisdn_len));
size += sizeof(target.msisdn_len);
ogs_assert(size + user_id->msisdn_len <= data_len);
memcpy((char *)octet->data + size,
user_id->msisdn, user_id->msisdn_len);
size += user_id->msisdn_len;
}
octet->len = size;
return octet->len;
}

View File

@ -1400,6 +1400,115 @@ int16_t ogs_pfcp_build_volume_measurement(ogs_tlv_octet_t *octet,
int16_t ogs_pfcp_parse_volume_measurement(
ogs_pfcp_volume_measurement_t *volume, ogs_tlv_octet_t *octet);
/*
* 8.2.101 User ID
*
* The User ID IE type shall be encoded as shown in Figure 8.2.101-1.
*
* The following flags are coded within Octet 5:
*
* -Bit 1 IMSIF: If this bit is set to "1",
* then the Length of IMSI and IMSI fields shall be present,
* otherwise these fields shall not be present.
* -Bit 2 IMEIF: If this bit is set to "1",
* then the Length of IMEI and IMEI fields shall be present,
* otherwise these fields shall not be present.
* -Bit 3 MSISDNF: If this bit is set to "1",
* then the Length of MSISDN and MSISDN fields shall be present,
* otherwise these fields shall not be present.
* -Bit 4 NAIF: If this bit is set to "1",
* then the Length of NAI and NAI fields shall be present,
* otherwise these fields shall not be present.
* -Bit 5 SUPIF: If this bit is set to "1",
* then the Length of SUPI and SUPI fields shall be present,
* otherwise these fields shall not be present.
* -Bit 6 GPSIF: If this bit is set to "1",
* then the Length of GPSI and GPSI fields shall be present,
* otherwise these fields shall not be present.
* -Bit 7 PEIF: If this bit is set to "1",
* then the Length of PEI and PEI fields shall be present,
* otherwise these fields shall not be present.
* - Bit 8: Spare, for future use and set to "0".
*
* One or more flags may be set to "1".
*
* For 5GS User Identities:
* -The SUPI field shall only be used for carrying a Global Cable Identifier
* (GCI) or a Global Line Identifier (GLI). The IMSI and NAI, if received
* by the SMF in the SUPI, shall be included in the IMSI and NAI field respectively.
* -The GPSI field shall only be used for carrying an External Identifier.
* The MSISDN, if received by the SMF in the SUPI, shall be included
* in the MSISDN field.
* -The PEI field shall only be used for carrying an MAC address or
* an Extended Unique Identifier. The IMEI, if received by the SMF in the PEI,
* shall be included in the IMEI field.
*
* The coding of IMSI field, from octets 7 to 'a' shall be encoded
* as the octets 5 to n+4 of the IMSI IE type
* specified in clause 8.3 of 3GPP TS 29.274 [9].
*
* The coding of IMEI field, in octets 'b+1' to 'c' shall be encoded
* as the octets 5 to n+4 of the MEI IE type
* specified in clause 8.10 of 3GPP TS 29.274 [9].
*
* The coding of MSISDN field, in octets 'd+1' to 'e' shall be encoded
* as the octets 5 to n+4 of the MSISDN IE type
* specified in clause 8.11 of 3GPP TS 29.274 [9].
*
* The coding of the SUPI field, in octets 'h+1' to 'i' shall be encoded
* as the Supi data type specified in clause 5.3.2 of 3GPP TS 29.571 [61].
*
* The coding of the GPSI field, in octets 'j+1' to 'k' shall be encoded
* as the Gpsi data type specified in clause 5.3.2 of 3GPP TS 29.571 [61].
*
* The coding of the PEI field, in octets 'l+1' to 'm' shall be encoded
* as the Pei data type specified in clause 5.3.2 of 3GPP TS 29.571 [61].
*
* The NAI field, in octets 'f+1' to 'g' shall be encoded as an Octet String
* (see IETF RFC 4282 [36]).
*/
typedef struct ogs_pfcp_user_id_flags_s {
union {
struct {
ED8(uint8_t spare:1;,
uint8_t peif:1;,
uint8_t gpsif:1;,
uint8_t supif:1;,
uint8_t naif:1;,
uint8_t msisdnf:1;,
uint8_t imeif:1;,
uint8_t imsif:1;)
};
uint8_t flags;
};
} ogs_pfcp_user_id_flags_t;
typedef struct ogs_pfcp_user_id_s {
union {
struct {
ED8(uint8_t spare:1;,
uint8_t peif:1;,
uint8_t gpsif:1;,
uint8_t supif:1;,
uint8_t naif:1;,
uint8_t msisdnf:1;,
uint8_t imeif:1;,
uint8_t imsif:1;)
};
uint8_t flags;
};
uint8_t imsi_len;
uint8_t imsi[OGS_MAX_IMSI_LEN];
uint8_t imeisv_len;
uint8_t imeisv[OGS_MAX_IMEISV_LEN];
uint8_t msisdn_len;
uint8_t msisdn[OGS_MAX_MSISDN_LEN];
} ogs_pfcp_user_id_t;
int16_t ogs_pfcp_build_user_id(
ogs_tlv_octet_t *octet, ogs_pfcp_user_id_t *user_id,
void *data, int data_len);
#ifdef __cplusplus
}

View File

@ -188,6 +188,7 @@ ogs_amf_id_t *ogs_amf_id_build(ogs_amf_id_t *amf_id,
* 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(char *str);
char *ogs_id_get_value(char *str);

View File

@ -57,21 +57,18 @@ int amf_nudm_sdm_handle_provisioned(
char *gpsi = NULL;
gpsi = ogs_id_get_type(node->data);
ogs_assert(gpsi);
if (gpsi) {
if (strncmp(gpsi, OGS_ID_GPSI_TYPE_MSISDN,
strlen(OGS_ID_GPSI_TYPE_MSISDN)) == 0) {
amf_ue->msisdn[amf_ue->num_of_msisdn] =
ogs_id_get_value(node->data);
ogs_assert(amf_ue->
msisdn[amf_ue->num_of_msisdn]);
if (strncmp(gpsi, OGS_ID_GPSI_TYPE_MSISDN,
strlen(OGS_ID_GPSI_TYPE_MSISDN)) != 0) {
ogs_error("Unknown GPSI Type [%s]", gpsi);
} else {
amf_ue->msisdn[amf_ue->num_of_msisdn] =
ogs_id_get_value(node->data);
ogs_assert(amf_ue->msisdn[amf_ue->num_of_msisdn]);
amf_ue->num_of_msisdn++;
amf_ue->num_of_msisdn++;
}
ogs_free(gpsi);
}
ogs_free(gpsi);
}
}
}

View File

@ -35,10 +35,17 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request(
ogs_pfcp_node_id_t node_id;
ogs_pfcp_f_seid_t f_seid;
char apn_dnn[OGS_MAX_DNN_LEN+1];
int len;
smf_ue_t *smf_ue = NULL;
ogs_pfcp_user_id_t user_id;
char user_id_buf[sizeof(ogs_pfcp_user_id_t)];
ogs_debug("Session Establishment Request");
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
req = &pfcp_message.pfcp_session_establishment_request;
memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t));
@ -102,6 +109,46 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request(
req->pdn_type.presence = 1;
req->pdn_type.u8 = sess->session.session_type;
/* User ID */
memset(&user_id, 0, sizeof(ogs_pfcp_user_id_t));
if (smf_ue->imsi_len) {
user_id.imsif = 1;
user_id.imsi_len = smf_ue->imsi_len;
ogs_assert(smf_ue->imsi_len <= OGS_MAX_IMSI_LEN);
memcpy(user_id.imsi, smf_ue->imsi, smf_ue->imsi_len);
}
if (smf_ue->imeisv_len) {
user_id.imeif = 1;
user_id.imeisv_len = smf_ue->imeisv_len;
ogs_assert(smf_ue->imeisv_len <= OGS_MAX_IMEISV_LEN);
memcpy(user_id.imeisv, smf_ue->imeisv, smf_ue->imeisv_len);
}
if (smf_ue->msisdn_len) {
user_id.msisdnf = 1;
user_id.msisdn_len = smf_ue->msisdn_len;
ogs_assert(smf_ue->msisdn_len <= OGS_MAX_MSISDN_LEN);
memcpy(user_id.msisdn, smf_ue->msisdn, smf_ue->msisdn_len);
}
if (user_id.flags) {
ogs_pfcp_build_user_id(
&req->user_id, &user_id, user_id_buf, sizeof(user_id_buf));
req->user_id.presence = 1;
}
/* APN/DNN */
len = ogs_fqdn_build(apn_dnn, sess->session.name, strlen(sess->session.name));
req->apn_dnn.presence = 1;
req->apn_dnn.len = len;
req->apn_dnn.data = apn_dnn;
/* S-NSSAI */
if (!sess->epc) {
req->s_nssai.presence = 1;
req->s_nssai.len = 4;
req->s_nssai.data = &sess->s_nssai;
}
pfcp_message.h.type = type;
pkbuf = ogs_pfcp_build_msg(&pfcp_message);

View File

@ -28,6 +28,7 @@ bool smf_nsmf_handle_create_sm_context(
{
bool rc;
smf_ue_t *smf_ue = NULL;
char *type = NULL;
ogs_nas_5gsm_header_t *gsm_header = NULL;
ogs_pkbuf_t *n1smbuf = NULL;
@ -164,6 +165,60 @@ bool smf_nsmf_handle_create_sm_context(
return false;
}
if (SmContextCreateData->supi) {
type = ogs_id_get_type(SmContextCreateData->supi);
if (type) {
if (strncmp(type, OGS_ID_SUPI_TYPE_IMSI,
strlen(OGS_ID_SUPI_TYPE_IMSI)) == 0) {
char *imsi_bcd = ogs_id_get_value(SmContextCreateData->supi);
ogs_cpystrn(smf_ue->imsi_bcd, imsi_bcd,
ogs_min(strlen(imsi_bcd), OGS_MAX_IMSI_BCD_LEN)+1);
ogs_bcd_to_buffer(smf_ue->imsi_bcd,
smf_ue->imsi, &smf_ue->imsi_len);
ogs_free(imsi_bcd);
}
ogs_free(type);
}
}
if (SmContextCreateData->pei) {
type = ogs_id_get_type(SmContextCreateData->pei);
if (type) {
if (strncmp(type, OGS_ID_SUPI_TYPE_IMEISV,
strlen(OGS_ID_SUPI_TYPE_IMEISV)) == 0) {
char *imeisv_bcd = ogs_id_get_value(SmContextCreateData->pei);
ogs_cpystrn(smf_ue->imeisv_bcd, imeisv_bcd,
ogs_min(strlen(imeisv_bcd), OGS_MAX_IMEISV_BCD_LEN)+1);
ogs_bcd_to_buffer(smf_ue->imeisv_bcd,
smf_ue->imeisv, &smf_ue->imeisv_len);
ogs_free(imeisv_bcd);
}
ogs_free(type);
}
}
if (SmContextCreateData->gpsi) {
type = ogs_id_get_type(SmContextCreateData->gpsi);
if (type) {
if (strncmp(type, OGS_ID_GPSI_TYPE_MSISDN,
strlen(OGS_ID_GPSI_TYPE_MSISDN)) == 0) {
char *msisdn_bcd = ogs_id_get_value(SmContextCreateData->gpsi);
ogs_cpystrn(smf_ue->msisdn_bcd, msisdn_bcd,
ogs_min(strlen(msisdn_bcd), OGS_MAX_MSISDN_BCD_LEN)+1);
ogs_bcd_to_buffer(smf_ue->msisdn_bcd,
smf_ue->msisdn, &smf_ue->msisdn_len);
ogs_free(msisdn_bcd);
}
ogs_free(type);
}
}
ogs_sbi_parse_plmn_id_nid(&sess->plmn_id, servingNetwork);
sess->sbi_rat_type = SmContextCreateData->rat_type;