From 773407e829e3f4b5d87a3d9b1956551aa804754a Mon Sep 17 00:00:00 2001 From: mamie1031 Date: Thu, 9 Jan 2025 23:57:11 -0800 Subject: [PATCH] feat: Modify code for indirect communication in free5gc v3.4.4 --- internal/context/context.go | 4 ++ internal/sbi/processor/nf_discovery.go | 75 ++++++++++++++++++++++++++ pkg/factory/config.go | 1 + pkg/factory/factory.go | 7 +++ 4 files changed, 87 insertions(+) diff --git a/internal/context/context.go b/internal/context/context.go index 3dcea3f..73a789d 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -28,6 +28,7 @@ type NRFContext struct { NrfCert *x509.Certificate NfRegistNum int nfRegistNumLock sync.RWMutex + ScpUri string } const ( @@ -47,6 +48,9 @@ func InitNrfContext() error { logger.InitLog.Infof("nrfconfig Info: Version[%s] Description[%s]", config.Info.Version, config.Info.Description) configuration := config.Configuration + if configuration.ScpUri != "" { + nrfContext.ScpUri = configuration.ScpUri + } nrfContext.NrfNfProfile.NfInstanceId = uuid.New().String() nrfContext.NrfNfProfile.NfType = models.NfType_NRF diff --git a/internal/sbi/processor/nf_discovery.go b/internal/sbi/processor/nf_discovery.go index 2524077..659bbe4 100644 --- a/internal/sbi/processor/nf_discovery.go +++ b/internal/sbi/processor/nf_discovery.go @@ -50,6 +50,7 @@ func validateQueryParameters(queryParameters url.Values) bool { "BSF": true, "CHF": true, "NWDAF": true, + "SCP": true, } var tgt, req string if queryParameters["target-nf-type"] != nil { @@ -173,6 +174,80 @@ func (p *Processor) NFDiscoveryProcedure(c *gin.Context, queryParameters url.Val } validityPeriod := 100 + // Indirect Communication + // Only the following NF pairs support indirect communication + supportNFPairForIndirectCommunication := false + npPairs := map[string][]string{ + "AMF": {"AUSF", "SMF"}, + "AUSF": {"UDM", "AMF"}, + "UDM": {"UDR", "AUSF"}, + "UDR": {"UDM", "NEF"}, + "SMF": {"AMF"}, + "NEF": {"UDR"}, + } + sourceNF := "" + targetNF := "" + if values, exists := queryParameters["requester-nf-type"]; exists && len(values) > 0 { + sourceNF = values[0] + } + if values, exists := queryParameters["target-nf-type"]; exists && len(values) > 0 { + targetNF = values[0] + } + + if validTargets, exists := npPairs[sourceNF]; exists { + for _, validTarget := range validTargets { + if validTarget == targetNF { + supportNFPairForIndirectCommunication = true + } + } + + } + ScpUri := nrf_context.GetSelf().ScpUri + if ScpUri != "" && supportNFPairForIndirectCommunication { + // parse uri to host and port + parsedURL, err := url.Parse(ScpUri) + if err != nil { + logger.DiscLog.Errorln("Error parsing URL:", err) + return + } + host := parsedURL.Host + hostParts := strings.Split(host, ":") + if len(hostParts) != 2 { + logger.DiscLog.Errorln("Invalid host format, expected IP:PORT") + return + } + ScpIp := hostParts[0] + scpPortInt, err := strconv.Atoi(hostParts[1]) + if err != nil { + logger.DiscLog.Errorln("Invalid port value: ", err) + } + logger.DiscLog.Infof("ScpIp: %v, scpPortInt: %v", ScpIp, scpPortInt) + logger.DiscLog.Infof("Discovery with indirect communication, the message will pass to SCP: [%v]", ScpUri) + if len(nfProfilesStruct) > 0 { + for i := range nfProfilesStruct { + nfProfilesStruct[i].Ipv4Addresses[0] = ScpUri + + if nfProfilesStruct[i].NfServices != nil { + for j := range *nfProfilesStruct[i].NfServices { + nfService := &(*nfProfilesStruct[i].NfServices)[j] + + if nfService.IpEndPoints != nil { + for k := range *nfService.IpEndPoints { + ipEndPoint := &(*nfService.IpEndPoints)[k] + ipEndPoint.Ipv4Address = ScpIp + ipEndPoint.Port = int32(scpPortInt) + } + } + // for UDM search + if nfService.ApiPrefix != "" { + nfService.ApiPrefix = ScpUri + } + } + } + } + } + + } // Build SearchResult model searchResult := &models.SearchResult{ ValidityPeriod: int32(validityPeriod), diff --git a/pkg/factory/config.go b/pkg/factory/config.go index d6a41bc..cab404c 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -61,6 +61,7 @@ type Configuration struct { MongoDBUrl string `yaml:"MongoDBUrl" valid:"required"` DefaultPlmnId models.PlmnId `yaml:"DefaultPlmnId" valid:"required"` ServiceNameList []string `yaml:"serviceNameList,omitempty" valid:"required"` + ScpUri string `yaml:"scpUri,omitempty"` } type Logger struct { diff --git a/pkg/factory/factory.go b/pkg/factory/factory.go index d26b2d8..ffb951f 100644 --- a/pkg/factory/factory.go +++ b/pkg/factory/factory.go @@ -30,6 +30,13 @@ func InitConfigFactory(f string, cfg *Config) error { if yamlErr := yaml.Unmarshal(content, cfg); yamlErr != nil { return fmt.Errorf("[Factory] %+v", yamlErr) } + // Check Communication Mode + if cfg.Configuration.ScpUri == "" { + logger.CfgLog.Infoln("Direct Communication Mode") + } else { + logger.CfgLog.Infof("Indirect Communication Mode, the control message will pass to SCP: [%v]", cfg.Configuration.ScpUri) + } + } return nil