open5gs/lib/nas/nas_types.c

223 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define TRACE_MODULE _nas_types
#include "core_debug.h"
#include "core_lib.h"
#include "nas_types.h"
static c_uint8_t br_calculate(
c_uint8_t *br, c_uint8_t *extended, c_uint8_t *extended2,
c_uint64_t input)
{
c_uint8_t length = 0;
/* Octet 3 : 00000000 Reserved, 11111111 0kbps */
if (input < 1)
{
*br = 0xff;
length = c_max(length, 1);
return length;
}
/*
* 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 256 Mbps to 65280 Mbps. */
if (input > (65200*1024))
{
*extended2 = 0b11111110;
length = c_max(length, 3);
input %= (256*1024);
}
else if (input >= (256*1024) && input <= (65200*1024))
{
*extended2 = input / (256*1024);
length = c_max(length, 3);
input %= (256*1024);
}
/* 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. */
if (input >= 1 && input <= 63)
{
*br = input;
length = c_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. */
else if (input >= 64 && input <= 568)
{
*br = ((input - 64) / 8) + 0b01000000;
length = c_max(length, 1);
}
/* Set to 568 Kbps */
else if (input > 568 && input < 576)
{
*br = 0b01111111;
length = c_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. */
else if (input >= 576 && input <= 8640)
{
*br = ((input - 576) / 64) + 0b10000000;
length = c_max(length, 1);
}
/* Set to 8640 Kbps */
else if (input > 8640 && input < 8700)
{
*br = 0b11111110;
length = c_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
* 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
* 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.
*/
else if (input >= 8700 && input <= 16000)
{
*br = 0b11111110;
*extended = ((input - 8600) / 100);
length = c_max(length, 2);
}
/* Set to 16000 Kbps */
else if (input > 16000 && input < (17*1024))
{
*br = 0b11111110;
*extended = 0b01001010;
length = c_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. */
else if (input >= (17*1024) && input <= (128*1024))
{
*br = 0b11111110;
*extended = ((input - (16*1024)) / (1*1024)) + 0b01001010;
length = c_max(length, 2);
}
/* Set to 128 Mbps */
else if (input > (128*1024) && input < (130*1024))
{
*br = 0b11111110;
*extended = 0b10111010;
length = c_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. */
else if (input >= (130*1024) && input <= (256*1024))
{
*br = 0b11111110;
*extended = ((input - (128*1024)) / (2*1024)) + 0b10111010;
length = c_max(length, 2);
}
return length;
}
void apn_ambr_build(
nas_apn_aggregate_maximum_bit_rate_t *apn_aggregate_maximum_bit_rate,
c_uint32_t dl_apn_ambr, c_uint32_t ul_apn_ambr)
{
c_uint8_t length = 0;
dl_apn_ambr = dl_apn_ambr / 1024; /* Kbps */
ul_apn_ambr = ul_apn_ambr / 1024; /* Kbps */
memset(apn_aggregate_maximum_bit_rate, 0,
sizeof(nas_apn_aggregate_maximum_bit_rate_t));
length = c_max(length, br_calculate(
&apn_aggregate_maximum_bit_rate->dl_apn_ambr,
&apn_aggregate_maximum_bit_rate->dl_apn_ambr_extended,
&apn_aggregate_maximum_bit_rate->dl_apn_ambr_extended2,
dl_apn_ambr));
length = c_max(length, br_calculate(
&apn_aggregate_maximum_bit_rate->ul_apn_ambr,
&apn_aggregate_maximum_bit_rate->ul_apn_ambr_extended,
&apn_aggregate_maximum_bit_rate->ul_apn_ambr_extended2,
ul_apn_ambr));
apn_aggregate_maximum_bit_rate->length = length*2;
}
void eps_qos_build(nas_eps_quality_of_service_t *eps_qos, c_uint8_t qci,
c_uint64_t dl_mbr, c_uint64_t ul_mbr, c_uint64_t dl_gbr, c_uint64_t ul_gbr)
{
c_uint8_t length = 0;
dl_mbr = dl_mbr / 1024; /* Kbps */
ul_mbr = ul_mbr / 1024; /* Kbps */
dl_gbr = dl_gbr / 1024; /* Kbps */
ul_gbr = ul_gbr / 1024; /* Kbps */
memset(eps_qos, 0, sizeof(nas_eps_quality_of_service_t));
eps_qos->qci = qci;
if (dl_mbr)
length = c_max(length, br_calculate(
&eps_qos->dl_mbr,
&eps_qos->dl_mbr_extended,
&eps_qos->dl_mbr_extended2,
dl_mbr));
if (ul_mbr)
length = c_max(length, br_calculate(
&eps_qos->ul_mbr,
&eps_qos->ul_mbr_extended,
&eps_qos->ul_mbr_extended2,
ul_mbr));
if (dl_gbr)
length = c_max(length, br_calculate(
&eps_qos->dl_gbr,
&eps_qos->dl_gbr_extended,
&eps_qos->dl_gbr_extended2,
dl_gbr));
if (ul_gbr)
length = c_max(length, br_calculate(
&eps_qos->ul_gbr,
&eps_qos->ul_gbr_extended,
&eps_qos->ul_gbr_extended2,
ul_gbr));
eps_qos->length = length*4+1;
}