[MME] fix the NAS encoding for AMBR (#967)

This commit is contained in:
Sukchan Lee 2021-05-05 21:16:31 +09:00
parent cea1dff5a1
commit 0b063a57c8
4 changed files with 90 additions and 68 deletions

View File

@ -208,6 +208,8 @@ static ogs_inline ogs_uint24_t ogs_htobe24(ogs_uint24_t x)
#define OGS_FILE_LINE __FILE__ ":" OGS_STRINGIFY(__LINE__)
#define ogs_uint64_to_uint32(x) ((x >= 0xffffffffUL) ? 0xffffffffU : x)
#ifdef __cplusplus
}
#endif

View File

@ -50,7 +50,10 @@ static uint8_t nas_ambr_from_kbps(
{
uint8_t length = 0;
/* Octet 3 : 00000000 Reserved, 11111111 0kbps */
/*
* Octet 3
* 11111111 0kbps
*/
if (input < 1) {
*br = 0xff;
length = ogs_max(length, 1);
@ -59,45 +62,32 @@ static uint8_t nas_ambr_from_kbps(
}
/*
* Octet 7 : 00000000
* Use the value indicated by the APN-AMBR for downlink and
* APN-AMBR for downlink (extended) in octets 3 and 5.
* Octet 3
*
* Octet 7 : 00000001 - 11111110
* The APN-AMBR is
* (the binary coded value in 8 bits) * 256 Mbps +
* "the value indicated by the APN-AMBR for downlink
* and APN-AMBR for downlink (extended) in octets 3 and 5",
* In network to UE direction:
* 00000000 Reserved
*
* giving a range of 256 Mbps to 65280 Mbps. */
if (input > (65200*1024)) {
ogs_error("Overflow : %ldkbps > 65200Mbps", (long)input);
*br = 0xff;
*extended2 = 0b11111110;
length = ogs_max(length, 3);
input %= (256*1024);
}
else if (input >= (256*1024) && input <= (65200*1024)) {
*extended2 = input / (256*1024);
*br = 0xff;
length = ogs_max(length, 3);
input %= (256*1024);
}
/* Octet 3 : 00000001 - 00111111
* Octet 3 : 00000001 - 00111111
* The APN-AMBR is binary coded in 8 bits, using a granularity of 1 kbps
* giving a range of values from 1 kbps to 63 kbps in 1 kbps increments. */
* giving a range of values from 1 kbps to 63 kbps in 1 kbps increments.
*
* Octet 3 : 01000000 - 01111111
* The APN-AMBR is
* 64 kbps + ((the binary coded value in 8 bits 01000000) * 8 kbps)
* giving a range of values from 64 kbps to 568 kbps in 8 kbps increments.
*
* Octet 3 : 10000000 - 11111110
* The APN-AMBR is
* 576 kbps + ((the binary coded value in 8 bits 10000000) * 64 kbps)
* giving a range of values from 576 kbps to 8640 kbps in 64 kbps increments
*/
/* giving a range of 1 kbps to 63 kbps in 1 kbps increments. */
if (input >= 1 && input <= 63) {
*br = input;
length = ogs_max(length, 1);
}
/* Octet 3 : 01000000 - 01111111
* The APN-AMBR is
* 64 kbps + ((the binary coded value in 8 bits 01000000) * 8 kbps)
* giving a range of values from 64 kbps to 568 kbps
* in 8 kbps increments. */
/* giving a range of 64 kbps to 568 kbps in 8 kbps increments. */
else if (input >= 64 && input <= 568) {
*br = ((input - 64) / 8) + 0b01000000;
length = ogs_max(length, 1);
@ -107,11 +97,7 @@ static uint8_t nas_ambr_from_kbps(
*br = 0b01111111;
length = ogs_max(length, 1);
}
/* Octet 3 : 10000000 - 111111110
* The APN-AMBR is
* 576 kbps + ((the binary coded value in 8 bits 10000000) * 64 kbps)
* giving a range of values from 576 kbps to 8640 kbps
* in 64 kbps increments. */
/* giving a range of 576 kbps to 8640 kbps in 64 kbps increments. */
else if (input >= 576 && input <= 8640) {
*br = ((input - 576) / 64) + 0b10000000;
length = ogs_max(length, 1);
@ -122,22 +108,29 @@ static uint8_t nas_ambr_from_kbps(
length = ogs_max(length, 1);
}
/* If the network wants to indicate an APN-AMBR
* for downlink higher than 8640 kbps,
* it shall set octet 3 to "11111110", i.e. 8640 kbps,
* and shall encode the value for the APN-AMBR in octet 5.
*
* Octet 5 : 00000000
/*
* Octet 5 : 00000000
* Use the value indicated by the APN-AMBR for downlink in octet 3.
*
* Octet 5 : All other values shall be interpreted as '11111010'.
*
* Octet 5 : 00000001 - 01001010
* Octet 5 : 00000001 - 01001010
* The APN-AMBR is
* 8600 kbps + ((the binary coded value in 8 bits) * 100 kbps),
* giving a range of values from 8700 kbps to 16000 kbps
* in 100 kbps increments.
*
* Octet 5 : 01001011 - 10111010
* The APN-AMBR is
* 16 Mbps + ((the binary coded value in 8 bits - 01001010) * 1 Mbps),
* giving a range of values from 17 Mbps to 128 Mbps in 1 Mbps increments.
*
* Octet 5 : 10111011 - 11111010
* 128 Mbps + (the binary coded value in 8 bits - 10111010) * 2 Mbps
* giving a range of 130 Mbps to 256 Mbps in 2 Mbps increments.
*
* All other values shall be interpreted as '11111010'.
*/
/* giving a range of 8700 kbps to 16000 kbps in 100 kbps increments. */
else if (input >= 8700 && input <= 16000) {
*br = 0b11111110;
*extended = ((input - 8600) / 100);
@ -149,11 +142,7 @@ static uint8_t nas_ambr_from_kbps(
*extended = 0b01001010;
length = ogs_max(length, 2);
}
/* Octet 5: 01001011 - 10111010
* The APN-AMBR is
* 16 Mbps + ((the binary coded value in 8 bits - 01001010) * 1 Mbps),
* giving a range of values from 17 Mbps to 128 Mbps
* in 1 Mbps increments. */
/* giving a range of 17 Mbps to 128 Mbps in 1 Mbps increments. */
else if (input >= (17*1024) && input <= (128*1024)) {
*br = 0b11111110;
*extended = ((input - (16*1024)) / (1*1024)) + 0b01001010;
@ -165,16 +154,45 @@ static uint8_t nas_ambr_from_kbps(
*extended = 0b10111010;
length = ogs_max(length, 2);
}
/* Octet 5: 10111011 - 11111010
* The APN-AMBR is
* 128 Mbps + ((the binary coded value in 8 bits - 10111010) * 2 Mbps),
* giving a range of values from 130 Mbps to 256 Mbps
* in 2 Mbps increments. */
/* giving a range of 130 Mbps to 256 Mbps in 2 Mbps increments. */
else if (input >= (130*1024) && input <= (256*1024)) {
*br = 0b11111110;
*extended = ((input - (128*1024)) / (2*1024)) + 0b10111010;
length = ogs_max(length, 2);
}
/* Set to 256 Mbps */
else if (input > (1*256*1024) && input < (2*256*1024)) {
*br = 0b11111110;
*extended = 0b11111010;
length = ogs_max(length, 2);
}
/*
* Octet 7 : 00000000
* Use the value indicated by the APN-AMBR for downlink and
* APN-AMBR for downlink (extended) in octets 3 and 5.
*
* Octet 7 : 00000001 - 11111110
* The APN-AMBR is
* (the binary coded value in 8 bits) * 256 Mbps +
* "the value indicated by the APN-AMBR for downlink
* and APN-AMBR for downlink (extended) in octets 3 and 5",
*/
/* giving a range of values from 260M to 500M in 4M increments */
else if (input >= (2*256*1024) && input <= (255*256*1024)) {
*br = 0b11111110;
*extended = 0b11111010;
*extended2 = (input - (1*256*1024)) / (256*1024);
length = ogs_max(length, 3);
}
/* if the sending entity want to indicate BR higher than 65280M */
else if (input > (255*256*1024)) {
*br = 0b11111110;
*extended = 0b11111010;
*extended2 = 0b11111110;
length = ogs_max(length, 3);
}
return length;
}
@ -208,7 +226,7 @@ static uint8_t nas_qos_from_kbps(
* Octet 4 : 00000001 - 00111111
* giving a range of 1 kbps to 63 kbps in 1 kbps increments.
*
* Octet 4 : 01000000 - 01111111
* Octet 4 : 01000000 - 01111111
* 64 kbps + (the binary coded value in 8 bits - 01000000) * 8 kbps
* giving a range of 64 kbps to 568 kbps in 8 kbps increments.
*

View File

@ -439,7 +439,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ret = fd_msg_avp_new(
ogs_diam_s6a_max_bandwidth_ul, 0, &avp_max_bandwidth_ul);
ogs_assert(ret == 0);
val.u32 = subscription_data.ambr.uplink;
val.u32 = ogs_uint64_to_uint32(subscription_data.ambr.uplink);
ret = fd_msg_avp_setvalue(avp_max_bandwidth_ul, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(
@ -448,7 +448,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ret = fd_msg_avp_new(
ogs_diam_s6a_max_bandwidth_dl, 0, &avp_max_bandwidth_dl);
ogs_assert(ret == 0);
val.u32 = subscription_data.ambr.downlink;
val.u32 = ogs_uint64_to_uint32(subscription_data.ambr.downlink);
ret = fd_msg_avp_setvalue(avp_max_bandwidth_dl, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(
@ -706,7 +706,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ret = fd_msg_avp_new(ogs_diam_s6a_max_bandwidth_ul, 0,
&avp_max_bandwidth_ul);
ogs_assert(ret == 0);
val.u32 = session->ambr.uplink;
val.u32 = ogs_uint64_to_uint32(session->ambr.uplink);
ret = fd_msg_avp_setvalue(avp_max_bandwidth_ul, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avp_ambr, MSG_BRW_LAST_CHILD,
@ -715,7 +715,7 @@ static int hss_ogs_diam_s6a_ulr_cb( struct msg **msg, struct avp *avp,
ret = fd_msg_avp_new(ogs_diam_s6a_max_bandwidth_dl, 0,
&avp_max_bandwidth_dl);
ogs_assert(ret == 0);
val.u32 = session->ambr.downlink;
val.u32 = ogs_uint64_to_uint32(session->ambr.downlink);
ret = fd_msg_avp_setvalue(avp_max_bandwidth_dl, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add(avp_ambr, MSG_BRW_LAST_CHILD,

View File

@ -464,7 +464,8 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
ret = fd_msg_avp_new(
ogs_diam_gx_apn_aggregate_max_bitrate_ul, 0, &avpch1);
ogs_assert(ret == 0);
val.u32 = gx_message.session_data.session.ambr.uplink;
val.u32 = ogs_uint64_to_uint32(
gx_message.session_data.session.ambr.uplink);
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
@ -475,7 +476,8 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp,
ret = fd_msg_avp_new(
ogs_diam_gx_apn_aggregate_max_bitrate_dl, 0, &avpch1);
ogs_assert(ret == 0);
val.u32 = gx_message.session_data.session.ambr.downlink;
val.u32 = ogs_uint64_to_uint32(
gx_message.session_data.session.ambr.downlink);
ret = fd_msg_avp_setvalue (avpch1, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
@ -1299,7 +1301,7 @@ static int encode_pcc_rule_definition(
ret = fd_msg_avp_new(
ogs_diam_gx_max_requested_bandwidth_ul, 0, &avpch3);
ogs_assert(ret == 0);
val.u32 = pcc_rule->qos.mbr.uplink;
val.u32 = ogs_uint64_to_uint32(pcc_rule->qos.mbr.uplink);
ret = fd_msg_avp_setvalue (avpch3, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3);
@ -1310,7 +1312,7 @@ static int encode_pcc_rule_definition(
ret = fd_msg_avp_new(
ogs_diam_gx_max_requested_bandwidth_dl, 0, &avpch3);
ogs_assert(ret == 0);
val.u32 = pcc_rule->qos.mbr.downlink;
val.u32 = ogs_uint64_to_uint32(pcc_rule->qos.mbr.downlink);
ret = fd_msg_avp_setvalue (avpch3, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3);
@ -1320,7 +1322,7 @@ static int encode_pcc_rule_definition(
if (pcc_rule->qos.gbr.uplink) {
ret = fd_msg_avp_new(ogs_diam_gx_guaranteed_bitrate_ul, 0, &avpch3);
ogs_assert(ret == 0);
val.u32 = pcc_rule->qos.gbr.uplink;
val.u32 = ogs_uint64_to_uint32(pcc_rule->qos.gbr.uplink);
ret = fd_msg_avp_setvalue (avpch3, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3);
@ -1330,7 +1332,7 @@ static int encode_pcc_rule_definition(
if (pcc_rule->qos.gbr.downlink) {
ret = fd_msg_avp_new(ogs_diam_gx_guaranteed_bitrate_dl, 0, &avpch3);
ogs_assert(ret == 0);
val.u32 = pcc_rule->qos.gbr.downlink;
val.u32 = ogs_uint64_to_uint32(pcc_rule->qos.gbr.downlink);
ret = fd_msg_avp_setvalue (avpch3, &val);
ogs_assert(ret == 0);
ret = fd_msg_avp_add (avpch2, MSG_BRW_LAST_CHILD, avpch3);