[SMF] Improve 3GPP-User-Location-Info in Gn,Gx,Gy (#1539)
* [GTP] Fix trailing whitespace * [SMF] Improve 3GPP-User-Location-Info in Gn,Gx,Gy
This commit is contained in:
parent
b2f2016a67
commit
46621538af
|
@ -125,9 +125,16 @@ extern struct dict_object *ogs_diam_gy_pre_emption_vulnerability;
|
|||
extern struct dict_object *ogs_diam_gy_apn_aggregate_max_bitrate_ul;
|
||||
extern struct dict_object *ogs_diam_gy_apn_aggregate_max_bitrate_dl;
|
||||
extern struct dict_object *ogs_diam_gy_3gpp_rat_type;
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_CGI 0
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_SAI 1
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_RAI 2
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI 128
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ECGI 129
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI 130
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ENODEB_ID 131
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ENODEB_ID 132
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_EXT_ENODEB_ID 133
|
||||
#define OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_EXT_ENODEB_ID 134
|
||||
extern struct dict_object *ogs_diam_gy_3gpp_user_location_info;
|
||||
extern struct dict_object *ogs_diam_gy_called_station_id;
|
||||
extern struct dict_object *ogs_diam_gy_3gpp_ms_timezone;
|
||||
|
|
|
@ -673,6 +673,16 @@ int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet)
|
|||
uli->lai.lac = be16toh(uli->lai.lac);
|
||||
size += sizeof(uli->lai);
|
||||
}
|
||||
if (uli->flags.enodeb_id) {
|
||||
ogs_assert(size + sizeof(uli->enodeb_id) <= octet->len);
|
||||
memcpy(&uli->enodeb_id,
|
||||
(unsigned char *)octet->data + size, sizeof(uli->enodeb_id));
|
||||
uli->enodeb_id.enodeb_id = be16toh(uli->enodeb_id.enodeb_id);
|
||||
size += sizeof(uli->enodeb_id);
|
||||
}
|
||||
if (uli->flags.ext_enodeb_id) { /* TODO */
|
||||
ogs_error("Extended Macro eNodeB ID in ULI not implemented! see 3GPP TS 29.274 8.21.8");
|
||||
}
|
||||
|
||||
ogs_assert(size == octet->len);
|
||||
|
||||
|
@ -742,6 +752,16 @@ int16_t ogs_gtp2_build_uli(
|
|||
&target.lai, sizeof(target.lai));
|
||||
size += sizeof(target.lai);
|
||||
}
|
||||
if (target.flags.enodeb_id) {
|
||||
ogs_assert(size + sizeof(target.enodeb_id) <= data_len);
|
||||
target.enodeb_id.enodeb_id = htobe16(target.enodeb_id.enodeb_id);
|
||||
memcpy((unsigned char *)octet->data + size,
|
||||
&target.enodeb_id, sizeof(target.enodeb_id));
|
||||
size += sizeof(target.enodeb_id);
|
||||
}
|
||||
if (uli->flags.ext_enodeb_id) { /* TODO */
|
||||
ogs_error("Extended Macro eNodeB ID in ULI not implemented! see 3GPP TS 29.274 8.21.8");
|
||||
}
|
||||
|
||||
octet->len = size;
|
||||
|
||||
|
|
|
@ -389,15 +389,29 @@ typedef struct ogs_gtp2_uli_e_cgi_s {
|
|||
uint32_t cell_id;
|
||||
} __attribute__ ((packed)) ogs_gtp2_uli_e_cgi_t;
|
||||
|
||||
typedef struct ogs_gtp2_uli_enodeb_id_s {
|
||||
ogs_nas_plmn_id_t nas_plmn_id;
|
||||
uint16_t enodeb_id;
|
||||
} __attribute__ ((packed)) ogs_gtp2_uli_enodeb_id_t;
|
||||
|
||||
typedef struct ogs_gtp2_uli_ext_enodeb_id_s {
|
||||
ogs_nas_plmn_id_t nas_plmn_id;
|
||||
uint32_t enodeb_id;
|
||||
} __attribute__ ((packed)) ogs_gtp2_uli_ext_enodeb_id_t;
|
||||
|
||||
typedef struct ogs_gtp2_uli_s {
|
||||
union {
|
||||
struct {
|
||||
ED7(uint8_t spare:2;,
|
||||
ED8(uint8_t ext_enodeb_id:1;,
|
||||
uint8_t enodeb_id:1;,
|
||||
uint8_t lai:1;,
|
||||
uint8_t e_cgi:1;,
|
||||
uint8_t tai:1;,
|
||||
uint8_t rai:1;,
|
||||
uint8_t sai:1;,
|
||||
uint8_t cgi:1;)
|
||||
};
|
||||
uint8_t octet;
|
||||
} flags;
|
||||
ogs_gtp2_uli_cgi_t cgi;
|
||||
ogs_gtp2_uli_sai_t sai;
|
||||
|
@ -405,6 +419,8 @@ typedef struct ogs_gtp2_uli_s {
|
|||
ogs_gtp2_uli_tai_t tai;
|
||||
ogs_gtp2_uli_e_cgi_t e_cgi;
|
||||
ogs_gtp2_uli_lai_t lai;
|
||||
ogs_gtp2_uli_enodeb_id_t enodeb_id;
|
||||
ogs_gtp2_uli_ext_enodeb_id_t ext_enodeb_id;
|
||||
} ogs_gtp2_uli_t;
|
||||
|
||||
int16_t ogs_gtp2_parse_uli(ogs_gtp2_uli_t *uli, ogs_tlv_octet_t *octet);
|
||||
|
|
|
@ -59,3 +59,89 @@ void smf_fd_final(void)
|
|||
|
||||
ogs_diam_final();
|
||||
}
|
||||
|
||||
/* Append 3GPP-User-Location-Info, 3GPP TS 29.061 16.4.7.2 22 */
|
||||
void smf_fd_msg_avp_add_3gpp_uli(smf_sess_t *sess, struct avp *avp)
|
||||
{
|
||||
struct avp *avpch1;
|
||||
union avp_value val;
|
||||
ogs_gtp2_uli_t uli;
|
||||
int16_t uli_len;
|
||||
uint8_t uli_buf[OGS_GTP2_MAX_ULI_LEN], reencoded_uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
uint8_t uli_type;
|
||||
int ret;
|
||||
ogs_gtp2_tlv_uli_t reencoded_uli;
|
||||
|
||||
if (sess->gtp.user_location_information.presence == 0)
|
||||
return;
|
||||
|
||||
if (sess->gtp.version == 1) {
|
||||
/* For GTPv1C, it's a 1-1 coding match with TS 29.060 7.7.51: */
|
||||
ret = fd_msg_avp_new(
|
||||
ogs_diam_gy_3gpp_user_location_info, 0, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = sess->gtp.user_location_information.data;
|
||||
val.os.len = sess->gtp.user_location_information.len;
|
||||
ret = fd_msg_avp_setvalue(avpch1, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GTPv2C and Diameter 3GPP-User-Location-Information encoding don't match */
|
||||
uli_len = ogs_gtp2_parse_uli(
|
||||
&uli, &sess->gtp.user_location_information);
|
||||
ogs_assert(sess->gtp.user_location_information.len == uli_len);
|
||||
|
||||
ogs_assert(sess->gtp.user_location_information.data);
|
||||
ogs_assert(sess->gtp.user_location_information.len);
|
||||
memcpy(&uli_buf, sess->gtp.user_location_information.data,
|
||||
sess->gtp.user_location_information.len);
|
||||
|
||||
/* Update Gy ULI Type */
|
||||
if (uli.flags.cgi) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_CGI;
|
||||
uli.flags.octet = 0; uli.flags.cgi = 1;
|
||||
} else if (uli.flags.sai) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_SAI;
|
||||
uli.flags.octet = 0; uli.flags.sai = 1;
|
||||
} else if (uli.flags.rai) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_RAI;
|
||||
uli.flags.octet = 0; uli.flags.rai = 1;
|
||||
} else if (uli.flags.tai && uli.flags.e_cgi) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI;
|
||||
uli.flags.octet = 0; uli.flags.tai = 1; uli.flags.e_cgi = 1;
|
||||
} else if (uli.flags.tai && uli.flags.enodeb_id) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ENODEB_ID;
|
||||
uli.flags.octet = 0; uli.flags.tai = 1; uli.flags.enodeb_id = 1;
|
||||
} else if (uli.flags.tai && uli.flags.ext_enodeb_id) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_EXT_ENODEB_ID;
|
||||
uli.flags.octet = 0; uli.flags.tai = 1; uli.flags.ext_enodeb_id = 1;
|
||||
} else if (uli.flags.tai) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI;
|
||||
uli.flags.octet = 0; uli.flags.tai = 1;
|
||||
} else if (uli.flags.e_cgi) {
|
||||
uli_type = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ECGI;
|
||||
uli.flags.octet = 0; uli.flags.e_cgi = 1;
|
||||
} else {
|
||||
ogs_error("Unexpected ULI content, unable to convert to Diameter!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reencode ULI dropping unrelated values: */
|
||||
uli_len = ogs_gtp2_build_uli(&reencoded_uli, &uli,
|
||||
reencoded_uli_buf, sizeof(reencoded_uli_buf));
|
||||
reencoded_uli_buf[0] = uli_type;
|
||||
|
||||
ret = fd_msg_avp_new(
|
||||
ogs_diam_gy_3gpp_user_location_info, 0, &avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = (uint8_t *)&reencoded_uli_buf;
|
||||
val.os.len = uli_len;
|
||||
ret = fd_msg_avp_setvalue(avpch1, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch1);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
|
|||
void smf_s6b_send_aar(smf_sess_t *sess, ogs_gtp_xact_t *xact);
|
||||
void smf_s6b_send_str(smf_sess_t *sess, ogs_gtp_xact_t *xact, uint32_t cause);
|
||||
|
||||
void smf_fd_msg_avp_add_3gpp_uli(smf_sess_t *sess, struct avp *avp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -141,10 +141,13 @@ uint8_t smf_gn_handle_create_pdp_context_request(
|
|||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
||||
/* User Location Information, TS 29.060 sec 7.7.51 */
|
||||
/* Note: the IE is content is different in GTPv1C and GTPv2C */
|
||||
OGS_TLV_STORE_DATA(&sess->gtp.user_location_information,
|
||||
&req->user_location_information);
|
||||
if (ogs_gtp1_parse_uli(&uli, &req->user_location_information) == 0)
|
||||
return OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT;
|
||||
|
||||
/* TODO: Copy uli->cgi/sai/rai into sess-> */
|
||||
switch (uli.geo_loc_type) {
|
||||
case OGS_GTP1_GEO_LOC_TYPE_CGI:
|
||||
ogs_nas_to_plmn_id(&sess->plmn_id, &uli.cgi.nas_plmn_id);
|
||||
|
@ -155,6 +158,7 @@ uint8_t smf_gn_handle_create_pdp_context_request(
|
|||
case OGS_GTP1_GEO_LOC_TYPE_RAI:
|
||||
ogs_nas_to_plmn_id(&sess->plmn_id, &uli.rai.nas_plmn_id);
|
||||
break;
|
||||
/* default: should not happen */
|
||||
}
|
||||
|
||||
/* Set MSISDN: */
|
||||
|
@ -203,15 +207,6 @@ uint8_t smf_gn_handle_create_pdp_context_request(
|
|||
&req->protocol_configuration_options);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Set User Location Information */
|
||||
/* TODO: the IE is probably different between GTPv1C and GTPv2, see what needs to be adapted */
|
||||
if (req->user_location_information.presence) {
|
||||
OGS_TLV_STORE_DATA(&sess->gtp.user_location_information,
|
||||
&req->user_location_information);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set UE Timezone */
|
||||
if (req->ms_time_zone.presence) {
|
||||
/* value part is compatible between UE Time Zone and MS Time Zone */
|
||||
|
|
|
@ -486,43 +486,8 @@ void smf_gx_send_ccr(smf_sess_t *sess, ogs_gtp_xact_t *xact,
|
|||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
|
||||
/* Set 3GPP-User-Location-Info */
|
||||
if (sess->gtp.user_location_information.presence) {
|
||||
ogs_gtp2_uli_t uli;
|
||||
int16_t uli_len;
|
||||
|
||||
uint8_t uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
|
||||
uli_len = ogs_gtp2_parse_uli(
|
||||
&uli, &sess->gtp.user_location_information);
|
||||
ogs_assert(sess->gtp.user_location_information.len == uli_len);
|
||||
|
||||
ogs_assert(sess->gtp.user_location_information.data);
|
||||
ogs_assert(sess->gtp.user_location_information.len);
|
||||
memcpy(&uli_buf, sess->gtp.user_location_information.data,
|
||||
sess->gtp.user_location_information.len);
|
||||
|
||||
/* Update Gx ULI Type */
|
||||
if (uli.flags.tai && uli.flags.e_cgi)
|
||||
uli_buf[0] =
|
||||
OGS_DIAM_GX_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI;
|
||||
else if (uli.flags.tai)
|
||||
uli_buf[0] = OGS_DIAM_GX_3GPP_USER_LOCATION_INFO_TYPE_TAI;
|
||||
else if (uli.flags.e_cgi)
|
||||
uli_buf[0] = OGS_DIAM_GX_3GPP_USER_LOCATION_INFO_TYPE_ECGI;
|
||||
|
||||
if (uli_buf[0]) {
|
||||
ret = fd_msg_avp_new(
|
||||
ogs_diam_gx_3gpp_user_location_info, 0, &avp);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = (uint8_t *)&uli_buf;
|
||||
val.os.len = sess->gtp.user_location_information.len;
|
||||
ret = fd_msg_avp_setvalue(avp, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
}
|
||||
/* 3GPP-User-Location-Info, 3GPP TS 29.061 16.4.7.2 22 */
|
||||
smf_fd_msg_avp_add_3gpp_uli(sess, avpch1);
|
||||
|
||||
/* Set 3GPP-MS-Timezone */
|
||||
if (sess->gtp.ue_timezone.presence &&
|
||||
|
|
|
@ -466,43 +466,8 @@ static void fill_service_information_ccr(smf_sess_t *sess,
|
|||
ogs_assert(ret == 0);
|
||||
}
|
||||
|
||||
/* 3GPP-User-Location-Info */
|
||||
if (sess->gtp.user_location_information.presence) {
|
||||
ogs_gtp2_uli_t uli;
|
||||
int16_t uli_len;
|
||||
|
||||
uint8_t uli_buf[OGS_GTP2_MAX_ULI_LEN];
|
||||
|
||||
uli_len = ogs_gtp2_parse_uli(
|
||||
&uli, &sess->gtp.user_location_information);
|
||||
ogs_assert(sess->gtp.user_location_information.len == uli_len);
|
||||
|
||||
ogs_assert(sess->gtp.user_location_information.data);
|
||||
ogs_assert(sess->gtp.user_location_information.len);
|
||||
memcpy(&uli_buf, sess->gtp.user_location_information.data,
|
||||
sess->gtp.user_location_information.len);
|
||||
|
||||
/* Update Gy ULI Type */
|
||||
if (uli.flags.tai && uli.flags.e_cgi)
|
||||
uli_buf[0] =
|
||||
OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI_AND_ECGI;
|
||||
else if (uli.flags.tai)
|
||||
uli_buf[0] = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_TAI;
|
||||
else if (uli.flags.e_cgi)
|
||||
uli_buf[0] = OGS_DIAM_GY_3GPP_USER_LOCATION_INFO_TYPE_ECGI;
|
||||
|
||||
if (uli_buf[0]) {
|
||||
ret = fd_msg_avp_new(
|
||||
ogs_diam_gy_3gpp_user_location_info, 0, &avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
val.os.data = (uint8_t *)&uli_buf;
|
||||
val.os.len = sess->gtp.user_location_information.len;
|
||||
ret = fd_msg_avp_setvalue(avpch2, &val);
|
||||
ogs_assert(ret == 0);
|
||||
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
|
||||
ogs_assert(ret == 0);
|
||||
}
|
||||
}
|
||||
/* 3GPP-User-Location-Info, 3GPP TS 29.061 16.4.7.2 22 */
|
||||
smf_fd_msg_avp_add_3gpp_uli(sess, avpch1);
|
||||
|
||||
if (sess->smf_ue->imeisv_len > 0) {
|
||||
/* User-Equipment-Info, 3GPP TS 32.299 7.1.17 */
|
||||
|
|
Loading…
Reference in New Issue