added "usage report" to user plane report (#1289)

Author: mhkndgn <hakan.dogan@b-ulltech.com>
Date:   Thu Dec 16 09:51:49 2021 +0300
This commit is contained in:
Sukchan Lee 2021-12-16 21:52:48 +09:00
parent e302f727fd
commit 9b40fe25ff
6 changed files with 359 additions and 35 deletions

View File

@ -568,7 +568,7 @@ void ogs_pfcp_build_create_urr(
message->measurement_method.presence = 1;
message->measurement_method.u8 = urr->meas_method;
message->reporting_triggers.presence = 1;
message->reporting_triggers.u24 = (urr->rep_triggers.reptri_5 << 16)
message->reporting_triggers.u24 = (urr->rep_triggers.reptri_5 << 16)
| (urr->rep_triggers.reptri_6 << 8)
| (urr->rep_triggers.reptri_7);
if (urr->meas_period) {
@ -702,6 +702,10 @@ void ogs_pfcp_build_create_bar(
message->bar_id.u8 = bar->id;
}
static struct {
ogs_pfcp_volume_measurement_t vol_meas;
} usage_report_buf;
ogs_pkbuf_t *ogs_pfcp_build_session_report_request(
uint8_t type, ogs_pfcp_user_plane_report_t *report)
{
@ -764,6 +768,57 @@ ogs_pkbuf_t *ogs_pfcp_build_session_report_request(
}
}
if (report->type.usage_report) {
req->usage_report.presence = 1;
req->usage_report.urr_id.presence = 1;
req->usage_report.urr_id.u32 = report->usage_report.id;
req->usage_report.ur_seqn.presence = 1;
req->usage_report.ur_seqn.u32 = report->usage_report.seqn;
req->usage_report.usage_report_trigger.presence = 1;
req->usage_report.usage_report_trigger.u24 =
(report->usage_report.rep_triggers.reptri_5 << 16)
| (report->usage_report.rep_triggers.reptri_6 << 8)
| (report->usage_report.rep_triggers.reptri_7);
if (report->usage_report.start_time) {
req->usage_report.start_time.presence = 1;
req->usage_report.start_time.u32 = report->usage_report.start_time;
}
if (report->usage_report.end_time) {
req->usage_report.end_time.presence = 1;
req->usage_report.end_time.u32 = report->usage_report.end_time;
}
if (report->usage_report.vol_measurement.flags) {
req->usage_report.volume_measurement.presence = 1;
ogs_pfcp_build_volume_measurement(
&req->usage_report.volume_measurement,
&report->usage_report.vol_measurement,
&usage_report_buf.vol_meas,
sizeof(usage_report_buf.vol_meas));
}
if (report->usage_report.dur_measurement) {
req->usage_report.duration_measurement.presence = 1;
req->usage_report.duration_measurement.u32 =
report->usage_report.dur_measurement;
}
if (report->usage_report.time_of_first_packet) {
req->usage_report.time_of_first_packet.presence = 1;
req->usage_report.time_of_first_packet.u32 =
report->usage_report.time_of_first_packet;
}
if (report->usage_report.time_of_last_packet) {
req->usage_report.time_of_last_packet.presence = 1;
req->usage_report.time_of_last_packet.u32 =
report->usage_report.time_of_last_packet;
}
}
if (report->error_indication.remote_f_teid_len) {
req->error_indication_report.presence = 1;
req->error_indication_report.remote_f_teid.presence = 1;

View File

@ -468,10 +468,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_measurement_method =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_usage_report_trigger =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT24,
"Usage Report Trigger",
OGS_PFCP_USAGE_REPORT_TRIGGER_TYPE,
0,
3,
0,
sizeof(ogs_pfcp_tlv_usage_report_trigger_t),
{ NULL }
@ -512,10 +512,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_volume_measurement =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_duration_measurement =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"Duration Measurement",
OGS_PFCP_DURATION_MEASUREMENT_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_duration_measurement_t),
{ NULL }
@ -523,10 +523,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_duration_measurement =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_time_of_first_packet =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"Time of First Packet",
OGS_PFCP_TIME_OF_FIRST_PACKET_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_time_of_first_packet_t),
{ NULL }
@ -534,10 +534,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_time_of_first_packet =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_time_of_last_packet =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"Time of Last Packet",
OGS_PFCP_TIME_OF_LAST_PACKET_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_time_of_last_packet_t),
{ NULL }
@ -589,10 +589,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_time_quota =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_start_time =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"Start Time",
OGS_PFCP_START_TIME_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_start_time_t),
{ NULL }
@ -600,10 +600,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_start_time =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_end_time =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"End Time",
OGS_PFCP_END_TIME_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_end_time_t),
{ NULL }
@ -798,10 +798,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_remote_gtp_u_peer =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_ur_seqn =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"UR-SEQN",
OGS_PFCP_UR_SEQN_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_ur_seqn_t),
{ NULL }

View File

@ -521,19 +521,19 @@ typedef ogs_tlv_octet_t ogs_pfcp_tlv_f_seid_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_node_id_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_pfd_contents_t;
typedef ogs_tlv_uint8_t ogs_pfcp_tlv_measurement_method_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_usage_report_trigger_t;
typedef ogs_tlv_uint24_t ogs_pfcp_tlv_usage_report_trigger_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_measurement_period_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_fq_csid_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_volume_measurement_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_duration_measurement_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_time_of_first_packet_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_time_of_last_packet_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_duration_measurement_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_time_of_first_packet_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_time_of_last_packet_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_quota_holding_time_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_dropped_dl_traffic_threshold_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_volume_quota_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_time_quota_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_start_time_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_end_time_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_start_time_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_end_time_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_urr_id_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_linked_urr_id_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_outer_header_creation_t;
@ -551,7 +551,7 @@ typedef ogs_tlv_octet_t ogs_pfcp_tlv_header_enrichment_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_measurement_information_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_node_report_type_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_remote_gtp_u_peer_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_ur_seqn_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_ur_seqn_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_activate_predefined_rules_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_deactivate_predefined_rules_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_far_id_t;

View File

@ -417,13 +417,20 @@ type_list["PFCPSMReq-Flags"]["size"] = 1 # Type 49
type_list["PFCPSRRsp-Flags"]["size"] = 1 # Type 50
type_list["PDR ID"]["size"] = 2 # Type 56
type_list["Measurement Method"]["size"] = 1 # Type 62
type_list["Usage Report Trigger"]["size"] = 3 # Type 63
type_list["Measurement Period"]["size"] = 4 # Type 64
type_list["Duration Measurement"]["size"] = 4 # Type 67
type_list["Time of First Packet"]["size"] = 4 # Type 69
type_list["Time of Last Packet"]["size"] = 4 # Type 70
type_list["Quota Holding Time"]["size"] = 4 # Type 71
type_list["Time Quota"]["size"] = 4 # Type 74
type_list["Start Time"]["size"] = 4 # Type 75
type_list["End Time"]["size"] = 4 # Type 76
type_list["URR ID"]["size"] = 4 # Type 81
type_list["BAR ID"]["size"] = 1 # Type 88
type_list["CP Function Features"]["size"] = 1 # Type 89
type_list["Recovery Time Stamp"]["size"] = 4 # Type 96
type_list["UR-SEQN"]["size"] = 4 # Type 104
type_list["FAR ID"]["size"] = 4 # Type 108
type_list["QER ID"]["size"] = 4 # Type 109
type_list["PDN Type"]["size"] = 1 # Type 113

View File

@ -561,3 +561,119 @@ int16_t ogs_pfcp_parse_dropped_dl_traffic_threshold(
return size;
}
int16_t ogs_pfcp_build_volume_measurement(ogs_tlv_octet_t *octet,
ogs_pfcp_volume_measurement_t *volume, void *data, int data_len)
{
ogs_pfcp_volume_measurement_t target;
int16_t size = 0;
ogs_assert(volume);
ogs_assert(octet);
ogs_assert(data);
ogs_assert(data_len >= sizeof(ogs_pfcp_volume_measurement_t));
ogs_assert(volume->flags);
octet->data = data;
memcpy(&target, volume, sizeof(ogs_pfcp_volume_measurement_t));
((unsigned char *)octet->data)[size] = target.flags;
size += sizeof(target.flags);
if (target.tovol) {
target.total_volume = htobe64(target.total_volume);
memcpy((unsigned char *)octet->data + size,
&target.total_volume, sizeof(target.total_volume));
size += sizeof(target.total_volume);
}
if (target.ulvol) {
target.uplink_volume = htobe64(target.uplink_volume);
memcpy((unsigned char *)octet->data + size,
&target.uplink_volume, sizeof(target.uplink_volume));
size += sizeof(target.uplink_volume);
}
if (target.dlvol) {
target.downlink_volume = htobe64(target.downlink_volume);
memcpy((unsigned char *)octet->data + size,
&target.downlink_volume, sizeof(target.downlink_volume));
size += sizeof(target.downlink_volume);
}
if (target.tonop) {
target.total_n_packets = htobe64(target.total_n_packets);
memcpy((unsigned char *)octet->data + size,
&target.total_n_packets, sizeof(target.total_n_packets));
size += sizeof(target.total_n_packets);
}
if (target.ulnop) {
target.uplink_n_packets = htobe64(target.uplink_n_packets);
memcpy((unsigned char *)octet->data + size,
&target.uplink_n_packets, sizeof(target.uplink_n_packets));
size += sizeof(target.uplink_n_packets);
}
if (target.dlnop) {
target.downlink_n_packets = htobe64(target.downlink_n_packets);
memcpy((unsigned char *)octet->data + size,
&target.downlink_n_packets, sizeof(target.downlink_n_packets));
size += sizeof(target.downlink_n_packets);
}
octet->len = size;
return octet->len;
}
int16_t ogs_pfcp_parse_volume_measurement(
ogs_pfcp_volume_measurement_t *volume, ogs_tlv_octet_t *octet)
{
int16_t size = 0;
ogs_assert(volume);
ogs_assert(octet);
memset(volume, 0, sizeof(ogs_pfcp_volume_measurement_t));
volume->flags = ((unsigned char *)octet->data)[size];
size += sizeof(volume->flags);
if (volume->tovol) {
memcpy(&volume->total_volume, (unsigned char *)octet->data + size,
sizeof(volume->total_volume));
volume->total_volume = be64toh(volume->total_volume);
size += sizeof(volume->total_volume);
}
if (volume->ulvol) {
memcpy(&volume->uplink_volume, (unsigned char *)octet->data + size,
sizeof(volume->uplink_volume));
volume->uplink_volume = be64toh(volume->uplink_volume);
size += sizeof(volume->uplink_volume);
}
if (volume->dlvol) {
memcpy(&volume->downlink_volume, (unsigned char *)octet->data + size,
sizeof(volume->downlink_volume));
volume->downlink_volume = be64toh(volume->downlink_volume);
size += sizeof(volume->downlink_volume);
}
if (volume->tonop) {
memcpy(&volume->total_n_packets, (unsigned char *)octet->data + size,
sizeof(volume->total_n_packets));
volume->total_n_packets = be64toh(volume->total_n_packets);
size += sizeof(volume->total_n_packets);
}
if (volume->ulnop) {
memcpy(&volume->uplink_n_packets, (unsigned char *)octet->data + size,
sizeof(volume->uplink_n_packets));
volume->uplink_n_packets = be64toh(volume->uplink_n_packets);
size += sizeof(volume->uplink_n_packets);
}
if (volume->dlnop) {
memcpy(&volume->downlink_n_packets, (unsigned char *)octet->data + size,
sizeof(volume->downlink_n_packets));
volume->downlink_n_packets = be64toh(volume->downlink_n_packets);
size += sizeof(volume->downlink_n_packets);
}
ogs_assert(size == octet->len);
return size;
}

View File

@ -920,19 +920,6 @@ ED4(uint8_t spare:5;,
};
} __attribute__ ((packed)) ogs_pfcp_smreq_flags_t;
typedef struct ogs_pfcp_user_plane_report_s {
ogs_pfcp_report_type_t type;
struct {
uint8_t pdr_id;
uint8_t paging_policy_indication_value;
uint8_t qfi;
} downlink_data;
struct {
ogs_pfcp_f_teid_t remote_f_teid;
int remote_f_teid_len;
} error_indication;
} ogs_pfcp_user_plane_report_t;
/*
* 8.2.40 Measurement Method
*
@ -1138,6 +1125,165 @@ int16_t ogs_pfcp_parse_dropped_dl_traffic_threshold(
ogs_pfcp_dropped_dl_traffic_threshold_t *threshold,
ogs_tlv_octet_t *octet);
/** 8.2.71 UR-SEQN
*
* The UR-SEQN (Usage Report Sequence Number) IE identifies the order
* in which a usage report is generated for a
* given URR. It shall be encoded as shown in Figure 8.2.71-1.
*
* The UR-SEQN value shall be encoded as an Unsigned32 binary integer value.
*/
typedef uint32_t ogs_pfcp_urr_ur_seqn_t;
/** 8.2.52 Start Time
*
* The Start Time IE indicates the time at which the UP function started
* to collect the charging information. It shall be encoded as shown
* in Figure 8.2.52-1.
*
* The Start Time field shall contain a UTC time. Octets 5 to 8 shall
* be encoded in the same format as the first four octets
* of the 64-bit timestamp format as defined in clause 6 of IETF RFC 5905 [12].
*
* NOTE: The encoding is defined as the time in seconds relative to 00:00:00
* on 1 January 1900.
*/
typedef uint32_t ogs_pfcp_start_time_t;
/** 8.2.53 End Time
* The End Time IE indicates the time at which the UP function ended
* to collect the charging information. It shall be encoded as shown
* in Figure 8.2.53-1.
*
* The End Time field shall contain a UTC time. Octets 5 to 8 shall be
* encoded in the same format as the first four octets of the 64-bit timestamp
* format as defined in clause 6 of IETF RFC 5905 [12].
*
* NOTE: The encoding is defined as the time in seconds relative to 00:00:00
* on 1 January 1900.
*/
typedef uint32_t ogs_pfcp_end_time_t;
/** 8.2.45 Duration Measurement
*
* The Duration Measurement IE type shall be encoded as shown
* in Figure 8.2.45-1. It contains the used time in seconds
*
* The Duration value shall be encoded as an Unsigned32 binary integer value.
*/
typedef uint32_t ogs_pfcp_duration_measurement_t;
/** 8.2.46 Time of First Packet
*
* The Time of First Packet IE indicates the time stamp for the first
* IP packet transmitted for a given usage report. It shall be encoded
* as shown in Figure 8.2.46-1.
*
* The End Time field shall contain a UTC time. Octets 5 to 8 shall
* be encoded in the same format as the first four octets
* of the 64-bit timestamp format as defined in clause 6 of IETF RFC 5905 [12].
*
* NOTE: The encoding is defined as the time in seconds relative to 00:00:00
* on 1 January 1900.
*/
typedef uint32_t ogs_pfcp_time_of_first_packet_t;
/** 8.2.47 Time of Last Packet
*
* The Time of Last Packet IE indicates the time stamp for the last
* IP packet transmitted for a given usage report. It shall be encoded
* as shown in Figure 8.2.47-1.
*
* The End Time field shall contain a UTC time. Octets 5 to 8 shall
* be encoded in the same format as the first four octets
* of the 64-bit timestamp format as defined in clause 6 of IETF RFC 5905 [12].
*
* NOTE: The encoding is defined as the time in seconds relative to 00:00:00
* on 1 January 1900.
*/
typedef uint32_t ogs_pfcp_time_of_last_packet_t;
/** 8.2.44 Volume Measurement
*
* The Volume Measurement IE contains the measured traffic volumes.
* It shall be encoded as shown in Figure 8.2.44-1.
*
* The following flags are coded within Octet 5:
*
* - Bit 1 TOVOL: If this bit is set to "1", then the Total Volume field
* shall be present, otherwise the Total Volume field shall not be present.
* - Bit 2 ULVOL: If this bit is set to "1", then the Uplink Volume field
* shall be present, otherwise the Uplink Volume field shall not be present.
* - Bit 3 DLVOL: If this bit is set to "1", then the Downlink Volume field
* shall be present, otherwise the Downlink Volume field shall not be present.
* - Bit 4 TONOP: If this bit is set to "1", then the Total Number of Packets
* field shall be present, otherwise the Total Number of Packets field
* shall not be present.
* - Bit 5 ULNOP: If this bit is set to "1", then the Uplink Number
* of Packets field shall be present, otherwise the Uplink Number
* of Packets field shall not be present.
* - Bit 6 DLNOP: If this bit is set to "1", then the Downlink Number
* of Packets field shall be present, otherwise the Downlink Number
* of Packets field shall not be present.
* - Bit 7 to bit 8: Spare, for future use and set to "0".
*
* At least one bit shall be set to "1". Several bits may be set to "1".
*
* The Total Volume, Uplink Volume and Downlink Volume fields shall be encoded
* as an Unsigned64 binary integer value. They shall contain the total,
* uplink or downlink number of octets respectively
*/
typedef struct ogs_pfcp_volume_measurement_s {
union {
struct {
ED7(uint8_t spare:2;,
uint8_t dlnop:1;,
uint8_t ulnop:1;,
uint8_t tonop:1;,
uint8_t dlvol:1;,
uint8_t ulvol:1;,
uint8_t tovol:1;)
};
uint8_t flags;
};
uint64_t total_volume;
uint64_t uplink_volume;
uint64_t downlink_volume;
uint64_t total_n_packets;
uint64_t uplink_n_packets;
uint64_t downlink_n_packets;
} __attribute__ ((packed)) ogs_pfcp_volume_measurement_t;
typedef struct ogs_pfcp_user_plane_report_s {
ogs_pfcp_report_type_t type;
struct {
uint8_t pdr_id;
uint8_t paging_policy_indication_value;
uint8_t qfi;
} downlink_data;
struct {
ogs_pfcp_urr_id_t id;
ogs_pfcp_urr_ur_seqn_t seqn;
ogs_pfcp_reporting_triggers_t rep_triggers;
ogs_pfcp_start_time_t start_time;
ogs_pfcp_end_time_t end_time;
ogs_pfcp_volume_measurement_t vol_measurement;
ogs_pfcp_duration_measurement_t dur_measurement;
ogs_pfcp_time_of_first_packet_t time_of_first_packet;
ogs_pfcp_time_of_last_packet_t time_of_last_packet;
} usage_report;
struct {
ogs_pfcp_f_teid_t remote_f_teid;
int remote_f_teid_len;
} error_indication;
} ogs_pfcp_user_plane_report_t;
int16_t ogs_pfcp_build_volume_measurement(ogs_tlv_octet_t *octet,
ogs_pfcp_volume_measurement_t *volume, void *data, int data_len);
int16_t ogs_pfcp_parse_volume_measurement(
ogs_pfcp_volume_measurement_t *volume, ogs_tlv_octet_t *octet);
#ifdef __cplusplus
}
#endif