2 // Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
16 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 // platform project (RICP).
19 package rmrmsghandlers
26 "e2mgr/services/rmrsender"
30 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
31 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
35 toReplaceTags = []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List", "success", "s1", "ng", "e1", "f1", "w1", "x1", "xn"}
38 type E2nodeConfigUpdateNotificationHandler struct {
40 rNibDataService services.RNibDataService
41 rmrSender *rmrsender.RmrSender
44 func NewE2nodeConfigUpdateNotificationHandler(logger *logger.Logger, rNibDataService services.RNibDataService, rmrSender *rmrsender.RmrSender) *E2nodeConfigUpdateNotificationHandler {
45 return &E2nodeConfigUpdateNotificationHandler{
47 rNibDataService: rNibDataService,
52 func (e *E2nodeConfigUpdateNotificationHandler) Handle(request *models.NotificationRequest) {
53 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - RAN name: %s - received E2_Config_Update. Payload: %x", request.RanName, request.Payload)
54 e2NodeConfig, err := e.parseE2NodeConfigurationUpdate(request.Payload)
56 e.logger.Errorf(err.Error())
60 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - RIC_E2_Node_Config_Update parsed successfully %+v", e2NodeConfig)
62 nodebInfo, err := e.rNibDataService.GetNodeb(request.RanName)
65 switch v := err.(type) {
66 case *common.ResourceNotFoundError:
67 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - failed to get nodeB, E2nodeConfigUpdate will not be processed further.")
69 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", request.RanName, v)
73 e.updateE2nodeConfig(e2NodeConfig, nodebInfo)
74 e.handleSuccessfulResponse(e2NodeConfig, request, nodebInfo)
77 func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
78 e.handleAddConfig(e2nodeConfig, nodebInfo)
79 e.handleUpdateConfig(e2nodeConfig, nodebInfo)
80 e.handleDeleteConfig(e2nodeConfig, nodebInfo)
81 e.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
84 func (e *E2nodeConfigUpdateNotificationHandler) compareConfigIDs(n1, n2 entities.E2NodeComponentConfig) bool {
85 if n1.E2NodeComponentInterfaceType != n2.E2NodeComponentInterfaceType {
89 switch n1.E2NodeComponentInterfaceType {
90 case entities.E2NodeComponentInterfaceType_ng:
91 return n1.GetE2NodeComponentInterfaceTypeNG().GetAmfName() == n2.GetE2NodeComponentInterfaceTypeNG().GetAmfName()
92 case entities.E2NodeComponentInterfaceType_xn:
93 // TODO -- Not supported yet
94 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type Xn is not supported")
95 case entities.E2NodeComponentInterfaceType_e1:
96 return n1.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() == n2.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId()
97 case entities.E2NodeComponentInterfaceType_f1:
98 return n1.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() == n2.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId()
99 case entities.E2NodeComponentInterfaceType_w1:
100 return n1.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() == n2.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId()
101 case entities.E2NodeComponentInterfaceType_s1:
102 return n1.GetE2NodeComponentInterfaceTypeS1().GetMmeName() == n2.GetE2NodeComponentInterfaceTypeS1().GetMmeName()
104 case entities.E2NodeComponentInterfaceType_x2:
105 // TODO -- Not supported yet
106 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type X2 is not supported")
108 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type not supported")
113 func (e *E2nodeConfigUpdateNotificationHandler) handleAddConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
114 var result []*entities.E2NodeComponentConfig
116 additionList := e2nodeConfig.ExtractConfigAdditionList()
117 for i, _ := range additionList {
118 result = append(result, &additionList[i])
121 if nodebInfo.NodeType == entities.Node_ENB {
122 nodebInfo.GetEnb().NodeConfigs = append(result, nodebInfo.GetEnb().NodeConfigs...)
125 nodebInfo.GetGnb().NodeConfigs = append(result, nodebInfo.GetGnb().NodeConfigs...)
129 func (e *E2nodeConfigUpdateNotificationHandler) handleUpdateConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
130 updateList := e2nodeConfig.ExtractConfigUpdateList()
131 if nodebInfo.GetNodeType() == entities.Node_GNB {
132 for i := 0; i < len(updateList); i++ {
134 if nodebInfo.GetNodeType() == entities.Node_GNB {
135 for j := 0; j < len(nodebInfo.GetGnb().NodeConfigs); j++ {
136 if e.compareConfigIDs(u, *nodebInfo.GetGnb().NodeConfigs[j]) {
137 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
138 nodebInfo.GetGnb().NodeConfigs[i] = &u
141 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - dint match")
147 for i := 0; i < len(updateList); i++ {
149 if nodebInfo.GetNodeType() == entities.Node_ENB {
150 for j := 0; j < len(nodebInfo.GetEnb().NodeConfigs); j++ {
151 v := nodebInfo.GetEnb().NodeConfigs[j]
152 if e.compareConfigIDs(u, *v) {
153 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
154 nodebInfo.GetEnb().NodeConfigs[i] = &u
164 func (e *E2nodeConfigUpdateNotificationHandler) handleDeleteConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
165 deleteList := e2nodeConfig.ExtractConfigDeletionList()
167 for _, u := range deleteList {
168 if nodebInfo.GetNodeType() == entities.Node_ENB {
169 for i, v := range nodebInfo.GetEnb().NodeConfigs {
170 if e.compareConfigIDs(u, *v) {
171 nodebInfo.GetEnb().NodeConfigs = removeIndex(nodebInfo.GetEnb().GetNodeConfigs(), i)
177 if nodebInfo.GetNodeType() == entities.Node_GNB {
178 for i, v := range nodebInfo.GetGnb().NodeConfigs {
179 if e.compareConfigIDs(u, *v) {
180 nodebInfo.GetGnb().NodeConfigs = removeIndex(nodebInfo.GetGnb().GetNodeConfigs(), i)
188 func removeIndex(s []*entities.E2NodeComponentConfig, index int) []*entities.E2NodeComponentConfig {
190 return append(s[:index], s[index+1:]...)
195 func (e *E2nodeConfigUpdateNotificationHandler) parseE2NodeConfigurationUpdate(payload []byte) (*models.E2nodeConfigurationUpdateMessage, error) {
196 e2nodeConfig := models.E2nodeConfigurationUpdateMessage{}
197 err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2nodeConfig.E2APPDU))
200 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - error in parsing request message: %+v", err)
203 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - Unmarshalling is successful %v", e2nodeConfig.E2APPDU.InitiatingMessage.ProcedureCode)
204 return &e2nodeConfig, nil
207 func (e *E2nodeConfigUpdateNotificationHandler) handleSuccessfulResponse(e2NodeConfigUpdate *models.E2nodeConfigurationUpdateMessage, request *models.NotificationRequest, nodebInfo *entities.NodebInfo) error {
208 e2nodeConfigUpdateResp := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(e2NodeConfigUpdate)
209 payLoad, err := xml.Marshal(e2nodeConfigUpdateResp)
211 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", payLoad)
214 payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
215 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Sending RIC_E2nodeConfigUpdate_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
216 msg := models.NewRmrMessage(rmrCgo.RIC_E2NODE_CONFIG_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
217 err = e.rmrSender.Send(msg)