Skip to content

Commit

Permalink
fix ci error
Browse files Browse the repository at this point in the history
  • Loading branch information
free5gc-org committed Sep 6, 2023
1 parent 0b8a092 commit b4a1941
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 74 deletions.
2 changes: 1 addition & 1 deletion internal/context/charging.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
type ChargingLevel uint8

// For a rating group that is pud session charging level, all volume in a pdu session will be charged
// For a rating group that is flow charging level (or Rating group level (32.255)),
// For a rating group that is flow charging level (or Rating group level (32.255)),
// only volume in a flow will be charged
const (
PduSessionCharging ChargingLevel = iota
Expand Down
2 changes: 1 addition & 1 deletion internal/pfcp/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func HandlePfcpSessionReportRequest(msg *pfcpUdp.Message) {

if req.ReportType.Usar && req.UsageReport != nil {
smContext.HandleReports(req.UsageReport, nil, nil, upfNodeID, "")
// After recieving the Usage Report, it should send charging request to the CHF
// After receiving the Usage Report, it should send charging request to the CHF
// and update the URR with the quota or other charging information according to
// the charging response
go func() {
Expand Down
6 changes: 4 additions & 2 deletions internal/pfcp/message/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ func urrToCreateURR(urr *context.URR) *pfcp.CreateURR {
}
if !urr.QuotaValidityTime.IsZero() {
createURR.QuotaValidityTime = &pfcpType.QuotaValidityTime{
QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000),
QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(
time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000),
}
}

Expand Down Expand Up @@ -336,7 +337,8 @@ func urrToUpdateURR(urr *context.URR) *pfcp.UpdateURR {
}
if urr.QuotaValidityTime.IsZero() {
updateURR.QuotaValidityTime = &pfcpType.QuotaValidityTime{
QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000),
QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(
time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000),
}
}

Expand Down
8 changes: 4 additions & 4 deletions internal/pfcp/message/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func SendPfcpAssociationReleaseRequest(upNodeID pfcpType.NodeID) (resMsg *pfcpUd
pfcpMsg, err := BuildPfcpAssociationReleaseRequest()
if err != nil {
logger.PfcpLog.Errorf("Build PFCP Association Release Request failed: %v", err)
return
return nil, err
}

message := &pfcp.Message{
Expand Down Expand Up @@ -148,7 +148,7 @@ func SendPfcpSessionEstablishmentRequest(
ctx, pdrList, farList, barList, qerList, urrList)
if err != nil {
logger.PfcpLog.Errorf("Build PFCP Session Establishment Request failed: %v", err)
return
return nil, err
}

message := &pfcp.Message{
Expand Down Expand Up @@ -231,7 +231,7 @@ func SendPfcpSessionModificationRequest(
ctx, pdrList, farList, barList, qerList, urrList)
if err != nil {
logger.PfcpLog.Errorf("Build PFCP Session Modification Request failed: %v", err)
return
return nil, err
}

seqNum := getSeqNumber()
Expand Down Expand Up @@ -305,7 +305,7 @@ func SendPfcpSessionDeletionRequest(upf *context.UPF, ctx *context.SMContext) (r
pfcpMsg, err := BuildPfcpSessionDeletionRequest()
if err != nil {
logger.PfcpLog.Errorf("Build PFCP Session Deletion Request failed: %v", err)
return
return nil, err
}
seqNum := getSeqNumber()
remoteSEID := ctx.PFCPContext[nodeIDtoIP.String()].RemoteSEID
Expand Down
22 changes: 17 additions & 5 deletions internal/sbi/consumer/converged_charging.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import (
"github.com/free5gc/smf/internal/logger"
)

func buildConvergedChargingRequest(smContext *smf_context.SMContext, multipleUnitUsage []models.MultipleUnitUsage) *models.ChargingDataRequest {
func buildConvergedChargingRequest(smContext *smf_context.SMContext,
multipleUnitUsage []models.MultipleUnitUsage,
) *models.ChargingDataRequest {
var triggers []models.Trigger

smfSelf := smf_context.GetSelf()
Expand Down Expand Up @@ -70,7 +72,9 @@ func buildConvergedChargingRequest(smContext *smf_context.SMContext, multipleUni
return req
}

func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType smf_context.RequestType, multipleUnitUsage []models.MultipleUnitUsage) (*models.ChargingDataResponse, *models.ProblemDetails, error) {
func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType smf_context.RequestType,
multipleUnitUsage []models.MultipleUnitUsage,
) (*models.ChargingDataResponse, *models.ProblemDetails, error) {
logger.ChargingLog.Info("Handle SendConvergedChargingRequest")

req := buildConvergedChargingRequest(smContext, multipleUnitUsage)
Expand All @@ -79,18 +83,26 @@ func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType
var httpResponse *http.Response
var err error

//select the appropriate converged charging service based on trigger type
// select the appropriate converged charging service based on trigger type
switch requestType {
case smf_context.CHARGING_INIT:
rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataPost(context.Background(), *req)
chargingDataRef := strings.Split(httpResponse.Header.Get("Location"), "/")
smContext.ChargingDataRef = chargingDataRef[len(chargingDataRef)-1]
case smf_context.CHARGING_UPDATE:
rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefUpdatePost(context.Background(), smContext.ChargingDataRef, *req)
rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefUpdatePost(
context.Background(), smContext.ChargingDataRef, *req)
case smf_context.CHARGING_RELEASE:
httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefReleasePost(context.Background(), smContext.ChargingDataRef, *req)
httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefReleasePost(context.Background(),
smContext.ChargingDataRef, *req)
}

defer func() {
if resCloseErr := httpResponse.Body.Close(); resCloseErr != nil {
logger.ChargingLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr)
}
}()

if err == nil {
return &rsp, nil, nil
} else if httpResponse != nil {
Expand Down
8 changes: 5 additions & 3 deletions internal/sbi/producer/callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import (
"github.com/free5gc/util/httpwrapper"
)

func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyRequest, smContextRef string) *httpwrapper.Response {
func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyRequest,
smContextRef string,
) *httpwrapper.Response {
logger.ChargingLog.Info("Handle Charging Notification")

problemDetails := chargingNotificationProcedure(chargingNotifyRequest, smContextRef)
Expand All @@ -23,7 +25,7 @@ func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyReque
}
}

// While recieve Charging Notification from CHF, SMF will send Charging Information to CHF and update UPF
// While receive Charging Notification from CHF, SMF will send Charging Information to CHF and update UPF
func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRef string) *models.ProblemDetails {
if smContext := smf_context.GetSMContextByRef(smContextRef); smContext != nil {
go func() {
Expand All @@ -43,7 +45,6 @@ func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRe
upfUrrMap[upfId] = append(upfUrrMap[upfId], urr)
}
}

}

for upfId, urrList := range upfUrrMap {
Expand All @@ -68,6 +69,7 @@ func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRe

return nil
}

func HandleSMPolicyUpdateNotify(smContextRef string, request models.SmPolicyNotification) *httpwrapper.Response {
logger.PduSessLog.Infoln("In HandleSMPolicyUpdateNotify")
decision := request.SmPolicyDecision
Expand Down
118 changes: 63 additions & 55 deletions internal/sbi/producer/charging_trigger.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package producer

import (
"strings"
"time"

"github.com/free5gc/openapi/models"
Expand Down Expand Up @@ -29,9 +28,9 @@ func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_cont

for _, urr := range urrList {
if chgInfo := smContext.ChargingInfo[urr.URRID]; chgInfo != nil {

rg := chgInfo.RatingGroup
logger.PduSessLog.Tracef("Recieve Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", urr.URRID, rg, chgInfo.ChargingMethod)
logger.PduSessLog.Tracef("Receive Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v",
urr.URRID, rg, chgInfo.ChargingMethod)
triggerTime := time.Now()

uu := models.UsedUnitContainer{
Expand All @@ -50,7 +49,8 @@ func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_cont
}
}

_, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_UPDATE, multipleUnitUsage)
_, problemDetails, err := consumer.SendConvergedChargingRequest(smContext,
smf_context.CHARGING_UPDATE, multipleUnitUsage)
if problemDetails != nil {
logger.ChargingLog.Errorf("Send Charging Data Request[Init] Failed Problem[%+v]", problemDetails)
} else if err != nil {
Expand All @@ -63,7 +63,8 @@ func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_cont
func ReleaseChargingSession(smContext *smf_context.SMContext) {
multipleUnitUsage := buildMultiUnitUsageFromUsageReport(smContext)

_, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_RELEASE, multipleUnitUsage)
_, problemDetails, err := consumer.SendConvergedChargingRequest(smContext,
smf_context.CHARGING_RELEASE, multipleUnitUsage)
if problemDetails != nil {
logger.ChargingLog.Errorf("Send Charging Data Request[Termination] Failed Problem[%+v]", problemDetails)
} else if err != nil {
Expand All @@ -78,7 +79,8 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) {
multipleUnitUsage := buildMultiUnitUsageFromUsageReport(smContext)

if len(multipleUnitUsage) != 0 {
rsp, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_UPDATE, multipleUnitUsage)
rsp, problemDetails, err := consumer.SendConvergedChargingRequest(smContext,
smf_context.CHARGING_UPDATE, multipleUnitUsage)

if problemDetails != nil {
logger.ChargingLog.Errorf("Send Charging Data Request[Update] Failed Problem[%+v]", problemDetails)
Expand Down Expand Up @@ -118,11 +120,11 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) {
if err != nil {
logger.PduSessLog.Warnf("Sending PFCP Session Modification Request to AN UPF error: %+v", err)
pfcpResponseStatus = smf_context.SessionUpdateFailed
} else {
logger.PduSessLog.Infoln("Received PFCP Session Modification Response")
pfcpResponseStatus = smf_context.SessionUpdateSuccess
}

logger.PduSessLog.Infoln("Received PFCP Session Modification Response")
pfcpResponseStatus = smf_context.SessionUpdateSuccess

rsp := rcvMsg.PfcpMessage.Body.(pfcp.PFCPSessionModificationResponse)
if rsp.Cause == nil || rsp.Cause.CauseValue != pfcpType.CauseRequestAccepted {
logger.PduSessLog.Warn("Received PFCP Session Modification Not Accepted Response from AN UPF")
Expand All @@ -144,11 +146,6 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) {
}
}

func getUpfIdFromKey(key string) string {
upfIdUrridStr := strings.Split(key, ":")
return upfIdUrridStr[0]
}

func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []models.MultipleUnitUsage {
var ratingGroupUnitUsagesMap map[int32]models.MultipleUnitUsage
var multipleUnitUsage []models.MultipleUnitUsage
Expand Down Expand Up @@ -181,7 +178,8 @@ func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []mode
}

rg := chgInfo.RatingGroup
logger.PduSessLog.Tracef("Recieve Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", ur.UrrId, rg, chgInfo.ChargingMethod)
logger.PduSessLog.Tracef("Receive Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v",
ur.UrrId, rg, chgInfo.ChargingMethod)
triggerTime := time.Now()

uu := models.UsedUnitContainer{
Expand Down Expand Up @@ -258,12 +256,15 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio
switch t.TriggerType {
case models.TriggerType_VOLUME_LIMIT:
// According to 32.255, the for the trigger "Expirt of datavolume limit" have tow reporting level
// In the Pdu sesion level, the report should be "Immediate report", that is this report should send to CHF immediately
// In the Rating Group level, the report should be "Defferd report", that is this report should send to CHF when the in the next charging request triggereed
// In the Pdu sesion level, the report should be "Immediate report",
// that is this report should send to CHF immediately
// In the Rating Group level, the report should be "Defferd report", that is this report should send to CHF
// when the in the next charging request triggereed
// by charging trigger that belongs to the type of immediate report

// TODO: Currently CHF cannot identify the report level since it only knows the rating group, so the both charging level of "Expirt of datavolume limit"
// will be included in the report, and the report type will be determined by the SMF
// TODO: Currently CHF cannot identify the report level since it only knows the rating group,
// so the both charging level of "Expirt of datavolume limit"
// will be included in the report, and the report type will be determined by the SMF
switch chgInfo.ChargingLevel {
case smf_context.PduSessionCharging:
if t.TriggerCategory == models.TriggerCategory_IMMEDIATE_REPORT {
Expand All @@ -274,18 +275,20 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio
chgInfo.VolumeLimitExpiryTimer = nil
}

chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) {
urrList := []*smf_context.URR{urr}
upf := smf_context.GetUpfById(ui.UPFID)
if upf != nil {
QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT)
ReportUsageAndUpdateQuota(smContext)
}
}, func() {
smContext.Log.Tracef("Volume Limit Expiry for Pdu session, it's rating group is [%d]", rg)
chgInfo.VolumeLimitExpiryTimer.Stop()
chgInfo.VolumeLimitExpiryTimer = nil
})
chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1,
func(expireTimes int32) {
urrList := []*smf_context.URR{urr}
upf := smf_context.GetUpfById(ui.UPFID)
if upf != nil {
QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT)
ReportUsageAndUpdateQuota(smContext)
}
},
func() {
smContext.Log.Tracef("Volume Limit Expiry for Pdu session, it's rating group is [%d]", rg)
chgInfo.VolumeLimitExpiryTimer.Stop()
chgInfo.VolumeLimitExpiryTimer = nil
})
}
case smf_context.FlowCharging:
if t.TriggerCategory == models.TriggerCategory_DEFERRED_REPORT {
Expand All @@ -296,43 +299,48 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio
chgInfo.VolumeLimitExpiryTimer = nil
}

chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) {
chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1,
func(expireTimes int32) {
urrList := []*smf_context.URR{urr}
upf := smf_context.GetUpfById(ui.UPFID)
if upf != nil {
QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT)
}
},
func() {
smContext.Log.Tracef("Volume Limit Expiry for rating group [%d]", rg)
chgInfo.VolumeLimitExpiryTimer.Stop()
chgInfo.VolumeLimitExpiryTimer = nil
})
}
}
case models.TriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS:
switch chgInfo.ChargingLevel {
case smf_context.PduSessionCharging:
chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1,
func(expireTimes int32) {
urrList := []*smf_context.URR{urr}
upf := smf_context.GetUpfById(ui.UPFID)
if upf != nil {
QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT)
ReportUsageAndUpdateQuota(smContext)
}
}, func() {
smContext.Log.Tracef("Volume Limit Expiry for rating group [%d]", rg)
chgInfo.VolumeLimitExpiryTimer.Stop()
chgInfo.VolumeLimitExpiryTimer = nil
},
func() {
smContext.Log.Tracef("Event Limit Expiry Timer is triggered")
chgInfo.EventLimitExpiryTimer = nil
})
}
}
case models.TriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS:
switch chgInfo.ChargingLevel {
case smf_context.PduSessionCharging:
chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1, func(expireTimes int32) {
urrList := []*smf_context.URR{urr}
upf := smf_context.GetUpfById(ui.UPFID)
if upf != nil {
QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT)
ReportUsageAndUpdateQuota(smContext)
}
}, func() {
smContext.Log.Tracef("Event Limit Expiry Timer is triggered")
chgInfo.EventLimitExpiryTimer = nil
})
default:
smContext.Log.Tracef("MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS should only be applied to PDU session level charging")
smContext.Log.Tracef("MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS" +
"should only be applied to PDU session level charging")
}
case models.TriggerType_QUOTA_THRESHOLD:
if ui.VolumeQuotaThreshold != 0 {
trigger.Volth = true
urr.VolumeThreshold = uint64(ui.VolumeQuotaThreshold)
}
// The difference between the quota validity time and the volume limit is that the validity time is counted by the UPF,
// the volume limit is counted by the SMF
// The difference between the quota validity time and the volume limit is
// that the validity time is counted by the UPF, the volume limit is counted by the SMF
case models.TriggerType_VALIDITY_TIME:
if ui.ValidityTime != 0 {
urr.ReportingTrigger.Quvti = true
Expand Down
4 changes: 3 additions & 1 deletion internal/sbi/producer/datapath.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ func ActivateUPFSession(
close(resChan)
}

func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF, urrs []*smf_context.URR, reportResaon models.TriggerType) {
func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF,
urrs []*smf_context.URR, reportResaon models.TriggerType,
) {
smContext.SMLock.Lock()
defer smContext.SMLock.Unlock()

Expand Down
2 changes: 0 additions & 2 deletions internal/sbi/producer/pdu_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,6 @@ func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmCo
// UE location change is a charging event
// TODO: This is not tested yet
if smContext.UeLocation != body.JsonData.UeLocation {
var urrList []*smf_context.URR

// All rating group related to this Pdu session should send charging request
for _, dataPath := range tunnel.DataPathPool {
if dataPath.Activated {
Expand Down

0 comments on commit b4a1941

Please sign in to comment.