diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 292f9209..2e5049e9 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -444,13 +444,26 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence logger.PduSessLog.Errorln("new QER failed") return } else { + var bitRateKbpsULMBR uint64 + var bitRateKbpsDLMBR uint64 + var bitRateConvertErr error + bitRateKbpsULMBR, bitRateConvertErr = util.BitRateTokbps(sessionRule.AuthSessAmbr.Uplink) + if bitRateConvertErr != nil { + logger.PduSessLog.Errorln("Cannot get the unit of ULMBR, please check the settings in web console") + return + } + bitRateKbpsDLMBR, bitRateConvertErr = util.BitRateTokbps(sessionRule.AuthSessAmbr.Downlink) + if bitRateConvertErr != nil { + logger.PduSessLog.Errorln("Cannot get the unit of DLMBR, please check the settings in web console") + return + } newQER.GateStatus = &pfcpType.GateStatus{ ULGate: pfcpType.GateOpen, DLGate: pfcpType.GateOpen, } newQER.MBR = &pfcpType.MBR{ - ULMBR: util.BitRateTokbps(sessionRule.AuthSessAmbr.Uplink), - DLMBR: util.BitRateTokbps(sessionRule.AuthSessAmbr.Downlink), + ULMBR: bitRateKbpsULMBR, + DLMBR: bitRateKbpsDLMBR, } ambrQER = newQER } @@ -849,19 +862,62 @@ func (p *DataPath) AddQoS(smContext *SMContext, qfi uint8, qos *models.QosData) DLGate: pfcpType.GateOpen, } if isGBRFlow(qos) { + var bitRateKbpsQoSGBRUL uint64 + var bitRateKbpsQoSGBRDL uint64 + var bitRateKbpsQoSMBRUL uint64 + var bitRateKbpsQoSMBRDL uint64 + var bitRateConvertErr error + bitRateKbpsQoSGBRUL, bitRateConvertErr = util.BitRateTokbps(qos.GbrUl) + if bitRateConvertErr != nil { + logger.PduSessLog.Panicln("Cannot get the unit of GBRUL, please check the settings in web console") + return + } + + bitRateKbpsQoSGBRDL, bitRateConvertErr = util.BitRateTokbps(qos.GbrDl) + if bitRateConvertErr != nil { + logger.PduSessLog.Panicln("Cannot get the unit of GBRDL, please check the settings in web console") + return + } + + bitRateKbpsQoSMBRUL, bitRateConvertErr = util.BitRateTokbps(qos.MaxbrUl) + if bitRateConvertErr != nil { + logger.PduSessLog.Panicln("Cannot get the unit of MBRUL, please check the settings in web console") + return + } + + bitRateKbpsQoSMBRDL, bitRateConvertErr = util.BitRateTokbps(qos.MaxbrDl) + if bitRateConvertErr != nil { + logger.PduSessLog.Panicln("Cannot get the unit of MBRDL, please check the settings in web console") + return + } + newQER.GBR = &pfcpType.GBR{ - ULGBR: util.BitRateTokbps(qos.GbrUl), - DLGBR: util.BitRateTokbps(qos.GbrDl), + ULGBR: bitRateKbpsQoSGBRUL, + DLGBR: bitRateKbpsQoSGBRDL, } newQER.MBR = &pfcpType.MBR{ - ULMBR: util.BitRateTokbps(qos.MaxbrUl), - DLMBR: util.BitRateTokbps(qos.MaxbrDl), + ULMBR: bitRateKbpsQoSMBRUL, + DLMBR: bitRateKbpsQoSMBRDL, } } else { + var bitRateKbpsSessionAmbrMBRUL uint64 + var bitRateKbpsSessionAmbrMBRDL uint64 + var bitRateConvertErr error + bitRateKbpsSessionAmbrMBRUL, bitRateConvertErr = util.BitRateTokbps(qos.MaxbrUl) + if bitRateConvertErr != nil { + logger.PduSessLog.Error("Cannot get the unit of MBRUL, please check the settings in web console") + return + } + bitRateKbpsSessionAmbrMBRDL, bitRateConvertErr = util.BitRateTokbps(qos.MaxbrDl) + + if bitRateConvertErr != nil { + logger.PduSessLog.Error("Cannot get the unit of MBRDL, please check the settings in web console") + return + } // Non-GBR flow should follows session-AMBR newQER.MBR = &pfcpType.MBR{ - ULMBR: util.BitRateTokbps(smContext.DnnConfiguration.SessionAmbr.Uplink), - DLMBR: util.BitRateTokbps(smContext.DnnConfiguration.SessionAmbr.Downlink), + ULMBR: bitRateKbpsSessionAmbrMBRUL, + DLMBR: bitRateKbpsSessionAmbrMBRDL, } } qer = newQER diff --git a/internal/util/qos_convert.go b/internal/util/qos_convert.go index 602814a1..c9adcd60 100644 --- a/internal/util/qos_convert.go +++ b/internal/util/qos_convert.go @@ -1,24 +1,29 @@ package util import ( + "errors" "strconv" "strings" "github.com/free5gc/ngap/ngapType" ) -func BitRateTokbps(bitrate string) uint64 { +func BitRateTokbps(bitrate string) (uint64, error) { s := strings.Split(bitrate, " ") var kbps uint64 var digit int if n, err := strconv.Atoi(s[0]); err != nil { - return 0 + return 0, nil } else { digit = n } + if len(s) == 1 { + return 0, errors.New("cannot get the unit of ULMBR/DLMBR/ULGBR/DLGBR, please check the settings in web console") + } + switch s[1] { case "bps": kbps = uint64(digit / 1000) @@ -31,7 +36,7 @@ func BitRateTokbps(bitrate string) uint64 { case "Tbps": kbps = uint64(digit * 1000000000) } - return kbps + return kbps, nil } func BitRateTombps(bitrate string) uint16 { diff --git a/internal/util/qos_convert_test.go b/internal/util/qos_convert_test.go new file mode 100644 index 00000000..b8aa4af0 --- /dev/null +++ b/internal/util/qos_convert_test.go @@ -0,0 +1,104 @@ +package util_test + +import ( + "testing" + + "github.com/free5gc/smf/internal/util" +) + +func TestBitRateToKbpsWithValidBpsBitRateShouldReturnValidKbpsBitRate(t *testing.T) { + var bitrate string = "1000 bps" + var correctBitRateKbps uint64 = 1 + + bitrateKbps, err := util.BitRateTokbps(bitrate) + + t.Log("Check: err should be nil since act should work correctly.") + if err != nil { + t.Errorf("Error: err should be nil but it returns %s", err) + } + t.Log("Check: convert should act correctly.") + if bitrateKbps != correctBitRateKbps { + t.Errorf("Error: bitrate convert failed. Expect: %d. Actually: %d", correctBitRateKbps, bitrateKbps) + } + t.Log("Passed.") +} + +func TestBitRateToKbpsWithValidKbpsBitRateShouldReturnValidKbpsBitRate(t *testing.T) { + var bitrate string = "1000 Kbps" + var correctBitRateKbps uint64 = 1000 + + bitrateKbps, err := util.BitRateTokbps(bitrate) + + t.Log("Check: err should be nil since act should work correctly.") + if err != nil { + t.Errorf("Error: err should be nil but it returns %s", err) + } + t.Log("Check: convert should act correctly.") + if bitrateKbps != correctBitRateKbps { + t.Errorf("Error: bitrate convert failed. Expect: %d. Actually: %d", correctBitRateKbps, bitrateKbps) + } + t.Log("Passed.") +} + +func TestBitRateToKbpsWithValidMbpsBitRateShouldReturnValidKbpsBitRate(t *testing.T) { + var bitrate string = "1000 Mbps" + var correctBitRateKbps uint64 = 1000000 + + bitrateKbps, err := util.BitRateTokbps(bitrate) + + t.Log("Check: err should be nil since act should work correctly.") + if err != nil { + t.Errorf("Error: err should be nil but it returns %s", err) + } + t.Log("Check: convert should act correctly.") + if bitrateKbps != correctBitRateKbps { + t.Errorf("Error: bitrate convert failed. Expect: %d. Actually: %d", correctBitRateKbps, bitrateKbps) + } + t.Log("Passed.") +} + +func TestBitRateToKbpsWithValidGbpsBitRateShouldReturnValidKbpsBitRate(t *testing.T) { + var bitrate string = "1000 Gbps" + var correctBitRateKbps uint64 = 1000000000 + + bitrateKbps, err := util.BitRateTokbps(bitrate) + + t.Log("Check: err should be nil since act should work correctly.") + if err != nil { + t.Errorf("Error: err should be nil but it returns %s", err) + } + t.Log("Check: convert should act correctly.") + if bitrateKbps != correctBitRateKbps { + t.Errorf("Error: bitrate convert failed. Expect: %d. Actually: %d", correctBitRateKbps, bitrateKbps) + } + t.Log("Passed.") +} + +func TestBitRateToKbpsWithValidTbpsBitRateShouldReturnValidKbpsBitRate(t *testing.T) { + var bitrate string = "1000 Tbps" + var correctBitRateKbps uint64 = 1000000000000 + + bitrateKbps, err := util.BitRateTokbps(bitrate) + + t.Log("Check: err should be nil since act should work correctly.") + if err != nil { + t.Errorf("Error: err should be nil but it returns %s", err) + } + t.Log("Check: convert should act correctly.") + if bitrateKbps != correctBitRateKbps { + t.Errorf("Error: bitrate convert failed. Expect: %d. Actually: %d", correctBitRateKbps, bitrateKbps) + } + t.Log("Passed.") +} + +func TestBitRateToKbpsWithInvalidBitRateShouldReturnError(t *testing.T) { + var bitrate string = "1000" // The unit is absent. It should raise error for `BitRateToKbps`. + + _, err := util.BitRateTokbps(bitrate) + + t.Log("Check: err should not be nil.") + if err == nil { + t.Error("Error: err should not be nil.") + } + t.Log("Passed.") +}