--- /dev/null
+// Copyright 2023 Nokia
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This source code is part of the near-RT RIC (RAN Intelligent Controller)
+// platform project (RICP)
+
+package rmrmsghandlers
+
+import (
+ "bytes"
+ "e2mgr/logger"
+ "e2mgr/managers"
+ "e2mgr/models"
+ "e2mgr/utils"
+ "encoding/xml"
+ "fmt"
+
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+ "sync"
+)
+
+var e2ErrorIndicationMessage = models.ErrorIndicationMessage{}
+
+var E2SETUP_PROCEDURE string = "1"
+var RICSERVICEUPDATE_PROCEDURE string = "7"
+
+type ErrorIndicationHandler struct {
+ logger *logger.Logger
+ ranDisconnectionManager managers.IRanDisconnectionManager
+ RicServiceUpdateManager managers.IRicServiceUpdateManager
+ procedureMapMutex sync.RWMutex
+}
+
+
+func ErrorIndicationNotificationHandler(logger *logger.Logger, ranDisconnectionManager managers.IRanDisconnectionManager, RicServiceUpdateManager managers.IRicServiceUpdateManager) *ErrorIndicationHandler {
+ return &ErrorIndicationHandler{
+ logger: logger,
+ ranDisconnectionManager: ranDisconnectionManager,
+ RicServiceUpdateManager: RicServiceUpdateManager,
+ }
+}
+func (errorIndicationHandler *ErrorIndicationHandler) Handle (request *models.NotificationRequest) {
+ ranName := request.RanName
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Received Error Indication from E2Node - %s", ranName)
+
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Received ErrorIndication payload at E2M is - %x", request.Payload)
+ errorIndicationMessage, err := errorIndicationHandler.parseErrorIndication(request.Payload)
+ if err != nil {
+ errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle- Parsing is not successful")
+ return
+ }
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle ERROR INDICATION from E2Node has been parsed successfully- %+v", errorIndicationMessage)
+ errorIndicationIE := errorIndicationMessage.E2APPDU.InitiatingMessage.Value.ErrorIndication.ProtocolIEs.ErrorIndicationIEs
+ fmt.Printf("errorIndicationIE value is %+v", errorIndicationIE)
+
+ for i := 0 ; i < len(errorIndicationIE) ; i++ {
+ if errorIndicationIE[i].ID == 2 {
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-CD is: %+v", errorIndicationIE[i].Value.CriticalityDiagnostics)
+ if errorIndicationIE[i].Value.CriticalityDiagnostics.ProcedureCode != "" && errorIndicationIE[i].Value.CriticalityDiagnostics.TriggeringMessage.SuccessfulOutcome != nil {
+ procedureCode := errorIndicationIE[i].Value.CriticalityDiagnostics.ProcedureCode
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-procedureCode present is: %+v", procedureCode)
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle- before triggeringMessage present is: %+v", errorIndicationIE[i].Value.CriticalityDiagnostics.TriggeringMessage)
+ triggeringMessageValue := &errorIndicationIE[i].Value.CriticalityDiagnostics.TriggeringMessage.SuccessfulOutcome
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-triggeringMessage present is: %+v", *triggeringMessageValue)
+ if procedureCode != "" && triggeringMessageValue != nil {
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.handleErrorIndicationBasedOnProcedureCode for all scenarios")
+ switch procedureCode {
+ case E2SETUP_PROCEDURE:
+ if triggeringMessageValue != nil {
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at E2Setup procedure")
+ err = errorIndicationHandler.ranDisconnectionManager.DisconnectRan(ranName)
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Cleanup Completed !!")
+ return
+ } else {
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication recieved for unsuccessful-outcome, no action taken")
+ }
+ case RICSERVICEUPDATE_PROCEDURE:
+ if triggeringMessageValue != nil {
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at Ric Service Update procedure")
+ err = errorIndicationHandler.RicServiceUpdateManager.RevertRanFunctions(ranName)
+ if err != nil {
+ errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-reverting RanFunctions and updating the nodebInfo failed due to error %+v", err)
+ }
+ return
+ } else {
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication recieved for unsuccessful-outcome, no action taken")
+ }
+ default:
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-problem in handling of error indication")
+ return
+ }
+ }
+ }
+ }
+ }
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-CriticalityDiagnostics IEs unsuccessful hence Retrieving based on procedureMap")
+ errorIndicationHandler.HandleBasedOnProcedureType(ranName)
+ errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Cleanup Completed !!")
+}
+
+
+
+func (errorIndicationHandler *ErrorIndicationHandler) HandleBasedOnProcedureType(ranName string) error {
+ errorIndicationHandler.procedureMapMutex.RLock()
+ procedureType, ok := models.ProcedureMap[ranName]
+ errorIndicationHandler.procedureMapMutex.RUnlock()
+ if !ok {
+ errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-Error ProcedureType not found for ranName %s", ranName)
+ } else {
+ switch procedureType {
+ case models.E2SetupProcedureCompleted:
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at E2Setup procedure")
+ err := errorIndicationHandler.ranDisconnectionManager.DisconnectRan(ranName)
+ if err != nil {
+ errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-Disconnect RAN and updating the nodebInfo failed due to error %+v", err)
+ }
+ case models.RicServiceUpdateCompleted:
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at Ric Service Update procedure")
+ err := errorIndicationHandler.RicServiceUpdateManager.RevertRanFunctions(ranName)
+ if err != nil {
+ errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-reverting RanFunctions and updating the nodebInfo failed due to error %+v", err)
+ }
+ case models.E2SetupProcedureFailure, models.RicServiceUpdateFailure:
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication occcured before successful outcome hence ignoring")
+ default:
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-Error in handling the ErrorIndication based on enum")
+ }
+ }
+ return nil
+}
+
+func (errorIndicationHandler *ErrorIndicationHandler) parseErrorIndication(payload []byte) (*models.ErrorIndicationMessage, error) {
+ pipInd := bytes.IndexByte(payload, '|')
+ if pipInd < 0 {
+ return nil, common.NewInternalError(fmt.Errorf("#ErrorIndicationHandler.parseErrorIndication - Error parsing ERROR INDICATION failed extract Payload: no | separator found"))
+ }
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.parseErrorIndication - payload: %s", payload)
+ errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.parseErrorIndication - payload: %s", payload[pipInd+1:])
+ errorIndicationMessage := &models.ErrorIndicationMessage{}
+ err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &errorIndicationMessage.E2APPDU)
+ if err != nil {
+ return nil, common.NewInternalError(fmt.Errorf("#ErrorIndicationHandler.parseErrorIndication - Error unmarshalling ERROR INDICATION payload: %x", payload))
+ }
+ return errorIndicationMessage, nil
+}
\ No newline at end of file