Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support traffic influence #29

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions internal/sbi/consumer/udr_service.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package consumer

import (
"errors"
"strconv"
"strings"
"sync"

"github.com/antihax/optional"

"github.com/free5gc/openapi"
"github.com/free5gc/openapi/Nudr_DataRepository"
"github.com/free5gc/openapi/models"
Expand Down Expand Up @@ -43,6 +46,53 @@ func (s *nudrService) getDataSubscription(uri string) *Nudr_DataRepository.APICl
return client
}

func (s *nudrService) GetAfInfluenceData(
ue *pcf_context.UeContext,
supi, dnn string,
interGrpIds []string,
sliceInfo *models.Snssai,
) (
tiData []models.TrafficInfluData,
problemDetails *models.ProblemDetails,
err error,
) {
client := s.getDataSubscription(ue.UdrUri)
ctx, pd, err := s.consumer.Context().GetTokenCtx(
models.ServiceName_NUDR_DR,
models.NfType_UDR)
if err != nil {
return []models.TrafficInfluData{}, pd, err
}

param := &Nudr_DataRepository.ApplicationDataInfluenceDataGetParamOpts{
Dnns: optional.NewInterface([]string{dnn}),
Snssais: optional.NewInterface(
util.MarshToJsonString([]models.Snssai{*sliceInfo}),
),
Supis: optional.NewInterface([]string{supi}),
InfluenceIds: optional.NewInterface(interGrpIds),
}

tiData, rsp, err := client.InfluenceDataApi.ApplicationDataInfluenceDataGet(ctx, param)
defer func() {
if rsp != nil {
if rsp.Body != nil {
if rsp.Body.Close() != nil {
logger.ConsumerLog.Errorf("getAfInfluenceData response body cannot close")
}
}
}
}()
if err != nil {
apiError := new(openapi.GenericOpenAPIError)
if ok := errors.As(err, &apiError); ok {
problemDetails = apiError.Model().(*models.ProblemDetails)
}
}

return tiData, problemDetails, err
}

func (s *nudrService) CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.SmPolicyContextData) (
subscriptionID string, problemDetails *models.ProblemDetails, err error,
) {
Expand Down
6 changes: 3 additions & 3 deletions internal/sbi/processor/ampolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ func (p *Processor) SendAMPolicyTerminationRequestNotification(ue *pcf_context.U

// returns UDR Uri of Ue, if ue.UdrUri dose not exist, query NRF to get supported Udr Uri
func (p *Processor) getUdrUri(ue *pcf_context.UeContext) string {
if ue.UdrUri != "" {
return ue.UdrUri
if ue.UdrUri == "" {
ue.UdrUri = p.Consumer().SendNFInstancesUDR(p.Context().NrfUri, ue.Supi)
}
return p.Consumer().SendNFInstancesUDR(p.Context().NrfUri, ue.Supi)
return ue.UdrUri
}
35 changes: 16 additions & 19 deletions internal/sbi/processor/smpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func (p *Processor) HandleCreateSmPolicyRequest(
}

chargingInterface, err := mongoapi.RestfulAPIGetOne(chargingDataColl, filterCharging, queryStrength)
var defaultChgData *models.ChargingData

if err != nil {
logger.SmPolicyLog.Errorf("Fail to get charging data to mongoDB err: %+v", err)
Expand All @@ -225,6 +226,7 @@ func (p *Processor) HandleCreateSmPolicyRequest(
ReportingLevel: models.ReportingLevel_RAT_GR_LEVEL,
MeteringMethod: models.MeteringMethod_VOLUME,
}
defaultChgData = chgData

switch chargingInterface["chargingMethod"].(string) {
case "Online":
Expand All @@ -250,6 +252,8 @@ func (p *Processor) HandleCreateSmPolicyRequest(
smPolicyData.ChargingIdGenerator++
}

chgDataMap := map[string]*models.ChargingData{}

logger.SmPolicyLog.Traceln("FlowRules for ueId:", ue.Supi, "snssai:", util.SnssaiModelsToHex(*request.SliceInfo))
for i, flowRule := range flowRulesInterface {
logger.SmPolicyLog.Tracef("flowRule %d: %s\n", i, openapi.MarshToJsonString(flowRule))
Expand Down Expand Up @@ -321,6 +325,7 @@ func (p *Processor) HandleCreateSmPolicyRequest(
ReportingLevel: models.ReportingLevel_RAT_GR_LEVEL,
MeteringMethod: models.MeteringMethod_VOLUME,
}
chgDataMap[val] = chgData

switch chargingInterface["chargingMethod"].(string) {
case "Online":
Expand Down Expand Up @@ -367,35 +372,27 @@ func (p *Processor) HandleCreateSmPolicyRequest(
smPolicyData.PolicyDecision = &decision
// TODO: PCC rule, PraInfo ...
// Get Application Data Influence Data from UDR
reqParam := Nudr_DataRepository.ApplicationDataInfluenceDataGetParamOpts{
Dnns: optional.NewInterface([]string{request.Dnn}),
Snssais: optional.NewInterface(util.MarshToJsonString([]models.Snssai{*request.SliceInfo})),
InternalGroupIds: optional.NewInterface(request.InterGrpIds),
Supis: optional.NewInterface([]string{request.Supi}),
}

ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NUDR_DR, models.NfType_UDR)
trafficInfluDatas, pd, err := p.Consumer().GetAfInfluenceData(
ue,
request.Supi,
request.Dnn,
request.InterGrpIds,
request.SliceInfo,
)
if err != nil {
c.JSON(int(pd.Status), pd)
return
}

udrClient := util.GetNudrClient(udrUri)
var resp *http.Response
trafficInfluDatas, resp, err := udrClient.InfluenceDataApi.
ApplicationDataInfluenceDataGet(ctx, &reqParam)
if err != nil || resp == nil || resp.StatusCode != http.StatusOK {
logger.SmPolicyLog.Warnf("Error response from UDR Application Data Influence Data Get")
}
if err = resp.Body.Close(); err != nil {
logger.SmPolicyLog.Warnf("failed to close response of Application Data Influence Data Get")
}
logger.SmPolicyLog.Infof("Matched [%d] trafficInfluDatas from UDR", len(trafficInfluDatas))
if len(trafficInfluDatas) != 0 {
// UE identity in UDR appData and apply appData to sm poliocy
var precedence int32 = 23
for _, tiData := range trafficInfluDatas {
pccRule := util.CreatePccRule(smPolicyData.PccRuleIdGenerator, precedence, nil, tiData.AfAppId)
// TODO: select charging data based on the filter (see chgDataMap)
util.SetPccRuleRelatedData(&decision, pccRule, nil, nil, defaultChgData, nil)
util.SetSmPolicyDecisionByTrafficInfluData(&decision, pccRule, tiData)
influenceID := getInfluenceID(tiData.ResUri)
if influenceID != "" {
Expand Down Expand Up @@ -436,13 +433,13 @@ func (p *Processor) HandleCreateSmPolicyRequest(
if bsfUri != "" {
bsfClient := util.GetNbsfClient(bsfUri)

ctx, pd, err = p.Context().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF)
ctx, pd, err := p.Context().GetTokenCtx(models.ServiceName_NBSF_MANAGEMENT, models.NfType_BSF)
if err != nil {
c.JSON(int(pd.Status), pd)
return
}

_, resp, err = bsfClient.PCFBindingsCollectionApi.CreatePCFBinding(ctx, pcfBinding)
_, resp, err := bsfClient.PCFBindingsCollectionApi.CreatePCFBinding(ctx, pcfBinding)
if err != nil || resp == nil || resp.StatusCode != http.StatusCreated {
logger.SmPolicyLog.Warnf("Create PCF binding data in BSF error[%+v]", err)
// Uncomment the following to return error response --> PDU SessEstReq will fail
Expand Down
Loading