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 if len(e2NodeConfig.E2APPDU.InitiatingMessage.Value.E2nodeConfigurationUpdate.ProtocolIEs.E2nodeConfigurationUpdateIEs) == 0 {
61 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - E2nodeConfigurationUpdateIEs is empty")
65 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - RIC_E2_Node_Config_Update parsed successfully %+v", e2NodeConfig)
67 nodebInfo, err := e.rNibDataService.GetNodeb(request.RanName)
70 switch v := err.(type) {
71 case *common.ResourceNotFoundError:
72 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - failed to get nodeB, E2nodeConfigUpdate will not be processed further.")
74 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", request.RanName, v)
78 e.updateE2nodeConfig(e2NodeConfig, nodebInfo)
79 e.handleSuccessfulResponse(e2NodeConfig, request, nodebInfo)
82 func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
83 e.handleAddConfig(e2nodeConfig, nodebInfo)
84 e.handleUpdateConfig(e2nodeConfig, nodebInfo)
85 e.handleDeleteConfig(e2nodeConfig, nodebInfo)
86 e.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
89 func (e *E2nodeConfigUpdateNotificationHandler) compareConfigIDs(n1, n2 entities.E2NodeComponentConfig) bool {
90 if n1.E2NodeComponentInterfaceType != n2.E2NodeComponentInterfaceType {
94 switch n1.E2NodeComponentInterfaceType {
95 case entities.E2NodeComponentInterfaceType_ng:
96 return n1.GetE2NodeComponentInterfaceTypeNG().GetAmfName() == n2.GetE2NodeComponentInterfaceTypeNG().GetAmfName()
97 case entities.E2NodeComponentInterfaceType_xn:
98 // TODO -- Not supported yet
99 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type Xn is not supported")
100 case entities.E2NodeComponentInterfaceType_e1:
101 return n1.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() == n2.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId()
102 case entities.E2NodeComponentInterfaceType_f1:
103 return n1.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() == n2.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId()
104 case entities.E2NodeComponentInterfaceType_w1:
105 return n1.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() == n2.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId()
106 case entities.E2NodeComponentInterfaceType_s1:
107 return n1.GetE2NodeComponentInterfaceTypeS1().GetMmeName() == n2.GetE2NodeComponentInterfaceTypeS1().GetMmeName()
109 case entities.E2NodeComponentInterfaceType_x2:
110 // TODO -- Not supported yet
111 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type X2 is not supported")
113 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type not supported")
118 func (e *E2nodeConfigUpdateNotificationHandler) handleAddConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
119 var result []*entities.E2NodeComponentConfig
121 additionList := e2nodeConfig.ExtractConfigAdditionList()
122 for i, _ := range additionList {
123 result = append(result, &additionList[i])
126 if nodebInfo.NodeType == entities.Node_ENB {
127 nodebInfo.GetEnb().NodeConfigs = append(result, nodebInfo.GetEnb().NodeConfigs...)
130 nodebInfo.GetGnb().NodeConfigs = append(result, nodebInfo.GetGnb().NodeConfigs...)
134 func (e *E2nodeConfigUpdateNotificationHandler) handleUpdateConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
135 updateList := e2nodeConfig.ExtractConfigUpdateList()
136 if nodebInfo.GetNodeType() == entities.Node_GNB {
137 for i := 0; i < len(updateList); i++ {
139 if nodebInfo.GetNodeType() == entities.Node_GNB {
140 for j := 0; j < len(nodebInfo.GetGnb().NodeConfigs); j++ {
141 if e.compareConfigIDs(u, *nodebInfo.GetGnb().NodeConfigs[j]) {
142 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
143 nodebInfo.GetGnb().NodeConfigs[i] = &u
146 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - dint match")
152 for i := 0; i < len(updateList); i++ {
154 if nodebInfo.GetNodeType() == entities.Node_ENB {
155 for j := 0; j < len(nodebInfo.GetEnb().NodeConfigs); j++ {
156 v := nodebInfo.GetEnb().NodeConfigs[j]
157 if e.compareConfigIDs(u, *v) {
158 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
159 nodebInfo.GetEnb().NodeConfigs[i] = &u
169 func (e *E2nodeConfigUpdateNotificationHandler) handleDeleteConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
170 deleteList := e2nodeConfig.ExtractConfigDeletionList()
172 for _, u := range deleteList {
173 if nodebInfo.GetNodeType() == entities.Node_ENB {
174 for i, v := range nodebInfo.GetEnb().NodeConfigs {
175 if e.compareConfigIDs(u, *v) {
176 nodebInfo.GetEnb().NodeConfigs = removeIndex(nodebInfo.GetEnb().GetNodeConfigs(), i)
182 if nodebInfo.GetNodeType() == entities.Node_GNB {
183 for i, v := range nodebInfo.GetGnb().NodeConfigs {
184 if e.compareConfigIDs(u, *v) {
185 nodebInfo.GetGnb().NodeConfigs = removeIndex(nodebInfo.GetGnb().GetNodeConfigs(), i)
193 func removeIndex(s []*entities.E2NodeComponentConfig, index int) []*entities.E2NodeComponentConfig {
195 return append(s[:index], s[index+1:]...)
200 func (e *E2nodeConfigUpdateNotificationHandler) parseE2NodeConfigurationUpdate(payload []byte) (*models.E2nodeConfigurationUpdateMessage, error) {
201 e2nodeConfig := models.E2nodeConfigurationUpdateMessage{}
202 err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2nodeConfig.E2APPDU))
205 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - error in parsing request message: %+v", err)
208 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - Unmarshalling is successful %v", e2nodeConfig.E2APPDU.InitiatingMessage.ProcedureCode)
209 return &e2nodeConfig, nil
212 func (e *E2nodeConfigUpdateNotificationHandler) handleSuccessfulResponse(e2NodeConfigUpdate *models.E2nodeConfigurationUpdateMessage, request *models.NotificationRequest, nodebInfo *entities.NodebInfo) error {
213 e2nodeConfigUpdateResp := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(e2NodeConfigUpdate)
214 payLoad, err := xml.Marshal(e2nodeConfigUpdateResp)
216 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", payLoad)
219 payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
220 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Sending RIC_E2nodeConfigUpdate_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
221 msg := models.NewRmrMessage(rmrCgo.RIC_E2NODE_CONFIG_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
222 err = e.rmrSender.Send(msg)