X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=E2Manager%2Fhandlers%2Frmrmsghandlers%2Fe2_setup_request_notification_handler.go;h=3f93c58df5bae9b8efc2ac45dd13749e9307dfbe;hb=refs%2Fchanges%2F66%2F12566%2F1;hp=259dcc3c0181481d19428c94579adbb37228a001;hpb=f37908ead01e7d9e3a64ab84e88878b58b3e3c42;p=ric-plt%2Fe2mgr.git diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go index 259dcc3..3f93c58 100644 --- a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go +++ b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go @@ -1,6 +1,8 @@ // // Copyright 2019 AT&T Intellectual Property // Copyright 2019 Nokia +// Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved. +// Copyright 2023 Capgemini // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,18 +31,24 @@ import ( "e2mgr/rmrCgo" "e2mgr/services" "e2mgr/services/rmrsender" + "e2mgr/utils" "encoding/xml" "errors" "fmt" - "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" - "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "strconv" "strings" + "time" + + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" ) +const cleanUpDurationNanoSec uint64 = 10000000000 // cleanUpDuration = 10sec (value in nanoSecond=10000000000) + var ( emptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "transport-resource-unavailable", "om-intervention", "request-id-unknown", - "v60s", "v20s", "v10s", "v5s", "v2s", "v1s"} + "unspecified", "message-not-compatible-with-receiver-state", "control-processing-overload", + "v60s", "v20s", "v10s", "v5s", "v2s", "v1s", "ng", "xn", "e1", "f1", "w1", "s1", "x2", "success", "failure"} gnbTypesMap = map[string]entities.GnbType{ "gnb": entities.GnbType_GNB, "en_gnb": entities.GnbType_EN_GNB, @@ -82,6 +90,7 @@ func NewE2SetupRequestNotificationHandler(logger *logger.Logger, config *configu func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationRequest) { ranName := request.RanName + models.UpdateProcedureType(ranName, models.E2SetupProcedureNotInitiated) h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - received E2_SETUP_REQUEST. Payload: %x", ranName, request.Payload) generalConfiguration, err := h.rNibDataService.GetGeneralConfiguration() @@ -91,14 +100,6 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR return } - h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - got general configuration from rnib - enableRic: %t", generalConfiguration.EnableRic) - - if !generalConfiguration.EnableRic { - cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}} - h.handleUnsuccessfulResponse(ranName, request, cause) - return - } - setupRequest, e2tIpAddress, err := h.parseSetupRequest(request.Payload) if err != nil { h.logger.Errorf(err.Error()) @@ -108,6 +109,15 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - E2T Address: %s - handling E2_SETUP_REQUEST", e2tIpAddress) h.logger.Debugf("#E2SetupRequestNotificationHandler.Handle - E2_SETUP_REQUEST has been parsed successfully %+v", setupRequest) + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - got general configuration from rnib - enableRic: %t", generalConfiguration.EnableRic) + + if !generalConfiguration.EnableRic { + cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}} + h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest) + models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure) + return + } + _, err = h.e2tInstancesManager.GetE2TInstance(e2tIpAddress) if err != nil { @@ -129,7 +139,8 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR if nodebInfo, err = h.handleNewRan(ranName, e2tIpAddress, setupRequest); err != nil { if _, ok := err.(*e2managererrors.UnknownSetupRequestRanNameError); ok { cause := models.Cause{RicRequest: &models.CauseRic{RequestIdUnknown: &struct{}{}}} - h.handleUnsuccessfulResponse(ranName, request, cause) + h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest) + models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure) } return } @@ -139,9 +150,12 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR functionsModified, err = h.handleExistingRan(ranName, nodebInfo, setupRequest) if err != nil { + h.fillCauseAndSendUnsuccessfulResponse(nodebInfo, request, setupRequest) + models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure) return } } + models.UpdateProcedureType(ranName, models.E2SetupProcedureOngoing) ranStatusChangePublished, err := h.e2tAssociationManager.AssociateRan(e2tIpAddress, nodebInfo) @@ -155,7 +169,8 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR } cause := models.Cause{Transport: &models.CauseTransport{TransportResourceUnavailable: &struct{}{}}} - h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause) + h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause, setupRequest) + models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure) } return } @@ -165,6 +180,8 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR } h.handleSuccessfulResponse(ranName, request, setupRequest) + models.UpdateProcedureType(ranName, models.E2SetupProcedureCompleted) + h.logger.Debugf("#E2SetupRequestNotificationHandler.Handle - updating the enum value to e2setup request completed") } func (h *E2SetupRequestNotificationHandler) handleUpdateAndPublishNodebInfo(functionsModified bool, ranStatusChangePublished bool, nodebInfo *entities.NodebInfo) error { @@ -211,15 +228,40 @@ func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAd } func (h *E2SetupRequestNotificationHandler) handleExistingRan(ranName string, nodebInfo *entities.NodebInfo, setupRequest *models.E2SetupRequestMessage) (bool, error) { - if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_SHUTTING_DOWN { + if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_DISCONNECTED { + delta_in_nano := uint64(time.Now().UnixNano()) - nodebInfo.StatusUpdateTimeStamp + //The duration from last Disconnection for which a new request is to be rejected (currently 10 sec) + if delta_in_nano < cleanUpDurationNanoSec { + h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity disconnection in progress", ranName, nodebInfo.ConnectionStatus) + return false, errors.New("nodeB entity disconnection in progress") + } + h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity in disconnected state", ranName, nodebInfo.ConnectionStatus) + } else if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_SHUTTING_DOWN { h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity in incorrect state", ranName, nodebInfo.ConnectionStatus) return false, errors.New("nodeB entity in incorrect state") } + nodebInfo.SetupFromNetwork = true + + e2NodeConfig := setupRequest.ExtractE2NodeConfigList() + if e2NodeConfig == nil { + return false, errors.New("Empty E2nodeComponentConfigAddition-List") + } + if nodebInfo.NodeType == entities.Node_ENB { + if len(e2NodeConfig) == 0 && len(nodebInfo.GetEnb().GetNodeConfigs()) == 0 { + return false, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetEnb().NodeConfigs = e2NodeConfig + return false, nil } + if len(e2NodeConfig) == 0 && len(nodebInfo.GetGnb().GetNodeConfigs()) == 0 { + return false, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetGnb().NodeConfigs = e2NodeConfig + setupMessageRanFuncs := setupRequest.ExtractRanFunctionsList() if setupMessageRanFuncs == nil || (len(setupMessageRanFuncs) == 0 && len(nodebInfo.GetGnb().RanFunctions) == 0) { @@ -230,8 +272,8 @@ func (h *E2SetupRequestNotificationHandler) handleExistingRan(ranName string, no return true, nil } -func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName string, req *models.NotificationRequest, cause models.Cause) { - failureResponse := models.NewE2SetupFailureResponseMessage(models.TimeToWaitEnum.V60s, cause) +func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName string, req *models.NotificationRequest, cause models.Cause, setupRequest *models.E2SetupRequestMessage) { + failureResponse := models.NewE2SetupFailureResponseMessage(models.TimeToWaitEnum.V60s, cause, setupRequest) h.logger.Debugf("#E2SetupRequestNotificationHandler.handleUnsuccessfulResponse - E2_SETUP_RESPONSE has been built successfully %+v", failureResponse) responsePayload, err := xml.Marshal(&failureResponse.E2APPDU) @@ -239,7 +281,7 @@ func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName s h.logger.Warnf("#E2SetupRequestNotificationHandler.handleUnsuccessfulResponse - RAN name: %s - Error marshalling RIC_E2_SETUP_RESP. Payload: %s", ranName, responsePayload) } - responsePayload = replaceEmptyTagsWithSelfClosing(responsePayload) + responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload, emptyTagsToReplaceToSelfClosingTags) h.logger.Infof("#E2SetupRequestNotificationHandler.handleUnsuccessfulResponse - payload: %s", responsePayload) msg := models.NewRmrMessage(rmrCgo.RIC_E2_SETUP_FAILURE, ranName, responsePayload, req.TransactionId, req.GetMsgSrc()) @@ -264,7 +306,7 @@ func (h *E2SetupRequestNotificationHandler) handleSuccessfulResponse(ranName str h.logger.Warnf("#E2SetupRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - Error marshalling RIC_E2_SETUP_RESP. Payload: %s", ranName, responsePayload) } - responsePayload = replaceEmptyTagsWithSelfClosing(responsePayload) + responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload, emptyTagsToReplaceToSelfClosingTags) h.logger.Infof("#E2SetupRequestNotificationHandler.handleSuccessfulResponse - payload: %s", responsePayload) @@ -290,21 +332,6 @@ func buildPlmnId(mmc string, mnc string) string { return b.String() } -func replaceEmptyTagsWithSelfClosing(responsePayload []byte) []byte { - - emptyTagVsSelfClosingTagPairs := make([]string, len(emptyTagsToReplaceToSelfClosingTags)*2) - - j := 0 - - for i := 0; i < len(emptyTagsToReplaceToSelfClosingTags); i++ { - emptyTagVsSelfClosingTagPairs[j] = fmt.Sprintf("<%[1]s>", emptyTagsToReplaceToSelfClosingTags[i]) - emptyTagVsSelfClosingTagPairs[j+1] = fmt.Sprintf("<%s/>", emptyTagsToReplaceToSelfClosingTags[i]) - j += 2 - } - responseString := strings.NewReplacer(emptyTagVsSelfClosingTagPairs...).Replace(string(responsePayload)) - return []byte(responseString) -} - func convertTo20BitString(ricNearRtId string) (string, error) { r, err := strconv.ParseUint(ricNearRtId, 16, 32) if err != nil { @@ -328,7 +355,7 @@ func (h *E2SetupRequestNotificationHandler) parseSetupRequest(payload []byte) (* h.logger.Infof("#E2SetupRequestNotificationHandler.parseSetupRequest - payload: %s", payload[pipInd+1:]) setupRequest := &models.E2SetupRequestMessage{} - err := xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU) + err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU) if err != nil { return nil, "", errors.New(fmt.Sprintf("#E2SetupRequestNotificationHandler.parseSetupRequest - Error unmarshalling E2 Setup Request payload: %x", payload)) } @@ -336,12 +363,6 @@ func (h *E2SetupRequestNotificationHandler) parseSetupRequest(payload []byte) (* return setupRequest, e2tIpAddress, nil } -func normalizeXml(payload []byte) []byte { - xmlStr := string(payload) - normalized := strings.NewReplacer("<", "<", ">", ">").Replace(xmlStr) - return []byte(normalized) -} - func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAddress string, request *models.E2SetupRequestMessage) (*entities.NodebInfo, error) { nodebInfo := &entities.NodebInfo{ AssociatedE2TInstanceAddress: e2tAddress, @@ -354,10 +375,37 @@ func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAd return nil, err } + e2NodeConfig := request.ExtractE2NodeConfigList() + if e2NodeConfig == nil { + return nil, errors.New("Empty E2nodeComponentConfigAddition-List") + } + if nodebInfo.NodeType == entities.Node_ENB { + if len(e2NodeConfig) == 0 && len(nodebInfo.GetEnb().GetNodeConfigs()) == 0 { + return nil, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetEnb().NodeConfigs = e2NodeConfig + return nodebInfo, nil } + if len(e2NodeConfig) == 0 && len(nodebInfo.GetGnb().GetNodeConfigs()) == 0 { + return nil, errors.New("Empty E2nodeComponentConfigAddition-List") + } + nodebInfo.GetGnb().NodeConfigs = e2NodeConfig + + if nodebInfo.NodeType == entities.Node_GNB { + h.logger.Debugf("#E2SetupRequestNotificationHandler buildNodebInfo - entities.Node_GNB %d", entities.Node_GNB) + + gnbNodetype := h.setGnbNodeType(request) + h.logger.Debugf("#E2SetupRequestNotificationHandler buildNodebInfo -gnbNodetype %s", gnbNodetype) + nodebInfo.GnbNodeType = gnbNodetype + nodebInfo.CuUpId = request.GetCuupId() + nodebInfo.DuId = request.GetDuId() + h.logger.Debugf("#E2SetupRequestNotificationHandler buildNodebInfo -cuupid%s", request.GetCuupId()) + h.logger.Debugf("#E2SetupRequestNotificationHandler buildNodebInfo -duid %s", request.GetDuId()) + } + ranFuncs := request.ExtractRanFunctionsList() if ranFuncs != nil { @@ -367,6 +415,24 @@ func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAd return nodebInfo, nil } + +func (h *E2SetupRequestNotificationHandler) setGnbNodeType(setupRequest *models.E2SetupRequestMessage) string { + gnbNodetype := "gNB" + /*Note: Deployment where CU-UP and DU are combined + (but do not include the CP-CP) and have a single E2 connection + is not supported. The combination of CU-CP, CU-UP, and DU will be + treated as a single gNB and expect it to have only the + global gNB ID in its E2 Setup ID*/ + if setupRequest.GetCuupId() != "" && setupRequest.GetDuId() != "" { + gnbNodetype = "gNB" + } else if setupRequest.GetCuupId() != "" { + gnbNodetype = "gNB_CU_UP" + } else if setupRequest.GetDuId() != "" { + gnbNodetype = "gNB_DU" + } + return gnbNodetype +} + func (h *E2SetupRequestNotificationHandler) setNodeTypeAndConfiguration(nodebInfo *entities.NodebInfo) error { for k, v := range gnbTypesMap { if strings.HasPrefix(nodebInfo.RanName, k) { @@ -399,3 +465,12 @@ func (h *E2SetupRequestNotificationHandler) buildNbIdentity(ranName string, setu GlobalNbId: h.buildGlobalNbId(setupRequest), } } + +func (h *E2SetupRequestNotificationHandler) fillCauseAndSendUnsuccessfulResponse(nodebInfo *entities.NodebInfo, request *models.NotificationRequest, setupRequest *models.E2SetupRequestMessage) { + ranName := request.RanName + if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_DISCONNECTED { + cause := models.Cause{Misc: &models.CauseMisc{ControlProcessingOverload: &struct{}{}}} + h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause, setupRequest) + models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure) + } +}