2 // Copyright (c) 2020 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
28 "e2mgr/services/rmrsender"
33 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
34 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
37 //type FunctionChange int
40 RAN_FUNCTIONS_ADDED int = 10 + iota
42 RAN_FUNCTIONS_MODIFIED
45 type functionDetails struct {
48 functionDefinition string
49 functionRevision uint32
53 type RicServiceUpdateHandler struct {
55 rmrSender *rmrsender.RmrSender
56 rNibDataService services.RNibDataService
57 ranListManager managers.RanListManager
60 func NewRicServiceUpdateHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, ranListManager managers.RanListManager) *RicServiceUpdateHandler {
61 return &RicServiceUpdateHandler{
64 rNibDataService: rNibDataService,
65 ranListManager: ranListManager,
69 func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) {
70 ranName := request.RanName
71 h.logger.Infof("#RicServiceUpdateHandler.Handle - RAN name: %s - received RIC_SERVICE_UPDATE. Payload: %s", ranName, request.Payload)
73 nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
75 _, ok := err.(*common.ResourceNotFoundError)
77 h.logger.Errorf("#RicServiceUpdateHandler.Handle - failed to get nodeB entity for ran name: %v due to RNIB Error: %s", ranName, err)
79 h.logger.Errorf("#RicServiceUpdateHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", ranName, err)
84 ricServiceUpdate, err := h.parseSetupRequest(request.Payload)
86 h.logger.Errorf(err.Error())
89 h.logger.Infof("#RicServiceUpdateHandler.Handle - RIC_SERVICE_UPDATE has been parsed successfully %+v", ricServiceUpdate)
91 ackFunctionIds := h.updateFunctions(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs, nodebInfo)
92 if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) > 1 {
93 err = h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
95 h.logger.Errorf("#RicServiceUpdateHandler.Handle - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err)
100 oldNbIdentity, newNbIdentity := h.ranListManager.UpdateHealthcheckTimeStampReceived(nodebInfo.RanName)
101 err = h.ranListManager.UpdateNbIdentities(nodebInfo.NodeType, []*entities.NbIdentity{oldNbIdentity}, []*entities.NbIdentity{newNbIdentity})
103 h.logger.Errorf("#RicServiceUpdate.Handle - failed to Update NbIdentities: %s", err)
107 updateAck := models.NewServiceUpdateAck(ackFunctionIds, ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs[0].Value.TransactionID)
108 err = h.sendUpdateAck(updateAck, nodebInfo, request)
110 h.logger.Errorf("#RicServiceUpdate.Handle - failed to send RIC_SERVICE_UPDATE_ACK message to RMR: %s", err)
114 h.logger.Infof("#RicServiceUpdate.Handle - Completed successfully")
117 func (h *RicServiceUpdateHandler) sendUpdateAck(updateAck models.RicServiceUpdateAckE2APPDU, nodebInfo *entities.NodebInfo, request *models.NotificationRequest) error {
118 payLoad, err := xml.Marshal(updateAck)
120 h.logger.Errorf("#RicServiceUpdate.sendUpdateAck - RAN name: %s - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", nodebInfo.RanName, payLoad)
123 toReplaceTags := []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List"}
124 payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
126 h.logger.Infof("#RicServiceUpdate.sendUpdateAck - Sending RIC_SERVICE_UPDATE_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
127 msg := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
128 err = h.rmrSender.Send(msg)
132 func (h *RicServiceUpdateHandler) updateFunctions(RICServiceUpdateIEs []models.RICServiceUpdateIEs, nodebInfo *entities.NodebInfo) []models.RicServiceAckRANFunctionIDItem {
133 ranFunctions := nodebInfo.GetGnb().RanFunctions
134 RanFIdtoIdxMap := make(map[uint32]int)
135 var acceptedFunctionIds []models.RicServiceAckRANFunctionIDItem
136 functionsToBeDeleted := make(map[int]bool)
138 for index, ranFunction := range ranFunctions {
139 RanFIdtoIdxMap[ranFunction.RanFunctionId] = index
142 for _, ricServiceUpdateIE := range RICServiceUpdateIEs {
143 functionDetails, err := h.getFunctionDetails(ricServiceUpdateIE)
145 h.logger.Errorf("#RicServiceUpdate.updateFunctions- GetFunctionDetails returned err: %s", err)
148 for _, functionDetail := range functionDetails {
149 functionChange, functionId, functionDefinition, functionRevision, functionOID := functionDetail.functionChange,
150 functionDetail.functionId, functionDetail.functionDefinition, functionDetail.functionRevision, functionDetail.functionOID
151 ranFIndex, ok := RanFIdtoIdxMap[functionId]
153 switch functionChange {
154 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
155 ranFunctions = append(ranFunctions, &entities.RanFunction{RanFunctionId: functionId,
156 RanFunctionDefinition: functionDefinition, RanFunctionRevision: functionRevision, RanFunctionOid: functionOID})
157 case RAN_FUNCTIONS_DELETED:
161 switch functionChange {
162 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
163 ranFunctions[ranFIndex].RanFunctionDefinition = functionDefinition
164 ranFunctions[ranFIndex].RanFunctionRevision = functionRevision
165 case RAN_FUNCTIONS_DELETED:
166 functionsToBeDeleted[ranFIndex] = true
169 serviceupdateAckFunctionId := models.RicServiceAckRANFunctionIDItem{RanFunctionID: functionId, RanFunctionRevision: functionRevision}
170 acceptedFunctionIds = append(acceptedFunctionIds, serviceupdateAckFunctionId)
173 finalranFunctions := h.remove(ranFunctions, functionsToBeDeleted)
174 nodebInfo.GetGnb().RanFunctions = finalranFunctions
175 return acceptedFunctionIds
178 func (h *RicServiceUpdateHandler) remove(ranFunctions []*entities.RanFunction, functionsToBeDeleted map[int]bool) []*entities.RanFunction {
179 if len(functionsToBeDeleted) == 0 {
182 var finalranFunctions []*entities.RanFunction
183 for i := 0; i < len(ranFunctions); i++ {
184 _, ok := functionsToBeDeleted[i]
186 finalranFunctions = append(finalranFunctions, ranFunctions[i])
189 return finalranFunctions
192 func (h *RicServiceUpdateHandler) getFunctionDetails(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
193 functionChange := ricServiceUpdateIE.ID
194 switch functionChange {
195 case RAN_FUNCTIONS_ADDED, RAN_FUNCTIONS_MODIFIED:
196 return h.getFunctionsAddedModifiedHandler(ricServiceUpdateIE)
197 case RAN_FUNCTIONS_DELETED:
198 return h.getFunctionsDeleteHandler(ricServiceUpdateIE)
200 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Unknown change type %v", functionChange))
202 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - Internal Error"))
205 func (h *RicServiceUpdateHandler) getFunctionsAddedModifiedHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
206 functionChange := ricServiceUpdateIE.ID
207 ranFunctionsIEList := ricServiceUpdateIE.Value.RANfunctionsList.RANfunctionsItemProtocolIESingleContainer
208 if len(ranFunctionsIEList) == 0 {
209 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but Functions list is empty", functionChange))
212 functionDetailsList := make([]functionDetails, len(ranFunctionsIEList))
213 for index, ranFunctionIE := range ranFunctionsIEList {
214 ranFunction := ranFunctionIE.Value.RANfunctionItem
215 functionDetailsList[index] = functionDetails{functionChange: functionChange, functionId: ranFunction.RanFunctionID,
216 functionDefinition: ranFunction.RanFunctionDefinition, functionRevision: ranFunction.RanFunctionRevision, functionOID: ranFunction.RanFunctionOID}
218 return functionDetailsList, nil
221 func (h *RicServiceUpdateHandler) getFunctionsDeleteHandler(ricServiceUpdateIE models.RICServiceUpdateIEs) ([]functionDetails, error) {
222 functionChange := ricServiceUpdateIE.ID
223 ranFunctionIdIEsList := ricServiceUpdateIE.Value.RANfunctionsIDList.RANfunctionsItemIDProtocolIESingleContainer
224 if len(ranFunctionIdIEsList) == 0 {
225 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdate.getFunctionDetails - function change type is %v but FunctionIds list is empty", functionChange))
228 functionDetailsList := make([]functionDetails, len(ranFunctionIdIEsList))
229 for index, ranFunctionIdIE := range ranFunctionIdIEsList {
230 ranFunctionId := ranFunctionIdIE.Value.RANfunctionIDItem
231 functionDetailsList[index] = functionDetails{functionChange: functionChange, functionId: ranFunctionId.RanFunctionID,
232 functionDefinition: "", functionRevision: ranFunctionId.RanFunctionRevision}
234 return functionDetailsList, nil
237 func (h *RicServiceUpdateHandler) parseSetupRequest(payload []byte) (*models.RICServiceUpdateMessage, error) {
238 pipInd := bytes.IndexByte(payload, '|')
240 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error parsing RIC SERVICE UPDATE failed extract Payload: no | separator found"))
243 ricServiceUpdate := &models.RICServiceUpdateMessage{}
244 err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &ricServiceUpdate.E2APPDU)
246 return nil, common.NewInternalError(fmt.Errorf("#RicServiceUpdateHandler.parseSetupRequest - Error unmarshalling RIC SERVICE UPDATE payload: %x", payload))
248 return ricServiceUpdate, nil