forked from acouzens/open5gs
[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:
parent
92efca1fbf
commit
5128ebc6c6
|
@ -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;
|
||||
}
|
||||
|
|
109
lib/pfcp/types.h
109
lib/pfcp/types.h
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue