E2 restart handling added
[ric-plt/submgr.git] / pkg / control / e2if_state.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package control
21
22 import (
23         "fmt"
24         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
25         "strings"
26         "sync"
27 )
28
29 type XappRnibIf struct {
30         XappRnibInterface
31 }
32
33 func (x *XappRnibIf) XappRnibSubscribe(NotificationCb func(string, ...string), channel string) error {
34         return xapp.Rnib.Subscribe(NotificationCb, channel)
35 }
36
37 func (x *XappRnibIf) XappRnibGetListGnbIds() ([]*xapp.RNIBNbIdentity, xapp.RNIBIRNibError) {
38         return xapp.Rnib.GetListGnbIds()
39 }
40 func (x *XappRnibIf) XappRnibGetNodeb(inventoryName string) (*xapp.RNIBNodebInfo, xapp.RNIBIRNibError) {
41         nodeInfo, err := xapp.Rnib.GetNodeb(inventoryName)
42         return nodeInfo, err
43 }
44
45 func CreateXappRnibIfInstance() XappRnibInterface {
46         return new(XappRnibIf)
47 }
48
49 type E2IfState struct {
50         mutex   sync.Mutex
51         control *Control
52         NbIdMap map[string]string
53 }
54
55 func (e *E2IfState) Init(c *Control) {
56         e.control = c
57         e.NbIdMap = make(map[string]string, 0)
58         e.ReadE2ConfigurationFromRnib()
59         e.SubscribeChannels()
60 }
61
62 func (e *E2IfState) NotificationCb(ch string, events ...string) {
63
64         xapp.Logger.Debug("SDL notification received from channel=%s, event=%v", ch, events[0])
65         if len(events) == 0 {
66                 xapp.Logger.Error("Invalid SDL notification received: %d", len(events))
67                 return
68         }
69
70         if strings.Contains(events[0], "_CONNECTED") {
71                 nbId, err := ExtractNbiIdFromString(events[0])
72                 if err != nil {
73                         xapp.Logger.Error("NotificationCb CONNECTED len(nbId) == 0 ")
74                         return
75                 }
76                 xapp.Logger.Debug("E2 CONNECTED. NbId=%s", nbId)
77                 e.NbIdMap[nbId] = nbId
78         } else if strings.Contains(events[0], "_DISCONNECTED") {
79                 nbId, err := ExtractNbiIdFromString(events[0])
80                 if err != nil {
81                         xapp.Logger.Error("NotificationCb DISCONNECTED len(nbId) == 0 ")
82                         return
83                 }
84                 xapp.Logger.Debug("E2 DISCONNECTED. NbId=%s", nbId)
85                 if _, ok := e.NbIdMap[nbId]; ok {
86                         delete(e.NbIdMap, nbId)
87                         e.control.registry.DeleteAllE2Subscriptions(nbId, e.control)
88                 }
89         }
90 }
91
92 func (e *E2IfState) SubscribeChannels() error {
93
94         if err := e.control.e2IfStateDb.XappRnibSubscribe(e.NotificationCb, "RAN_CONNECTION_STATUS_CHANGE"); err != nil {
95                 xapp.Logger.Error("Sdl.SubscribeChannel failed: %v", err)
96                 return err
97         }
98         xapp.Logger.Debug("Subscription to RAN state changes done!")
99         return nil
100 }
101
102 func (e *E2IfState) ReadE2ConfigurationFromRnib() {
103
104         xapp.Logger.Debug("ReadE2ConfigurationFromRnib()")
105         nbIdentities, err := e.control.e2IfStateDb.XappRnibGetListGnbIds()
106         if err != nil || len(nbIdentities) == 0 {
107                 xapp.Logger.Debug("There are no active NodeBs available: %v", err)
108                 e.NbIdMap = make(map[string]string, 0)
109                 return
110         }
111
112         for _, nbIdentity := range nbIdentities {
113                 if e.isNodeBActive(nbIdentity.InventoryName) == false {
114                         if _, ok := e.NbIdMap[nbIdentity.InventoryName]; ok {
115                                 delete(e.NbIdMap, nbIdentity.InventoryName)
116                                 e.control.UpdateCounter(cE2StateChangedToDown)
117                                 xapp.Logger.Debug("E2 connection DISCONNETED: %v", nbIdentity.InventoryName)
118
119                                 // Delete all subscriptions related to InventoryName/nbId
120                                 e.control.registry.DeleteAllE2Subscriptions(nbIdentity.InventoryName, e.control)
121                         }
122                         continue
123                 }
124
125                 if _, ok := e.NbIdMap[nbIdentity.InventoryName]; !ok {
126                         e.NbIdMap[nbIdentity.InventoryName] = nbIdentity.InventoryName
127                         e.control.UpdateCounter(cE2StateChangedToDown)
128                         xapp.Logger.Debug("E2 connection CONNECTED: %v", nbIdentity.InventoryName)
129                 }
130         }
131 }
132
133 func (e *E2IfState) isNodeBActive(inventoryName string) bool {
134         nodeInfo, err := e.control.e2IfStateDb.XappRnibGetNodeb(inventoryName)
135         if err != nil {
136                 xapp.Logger.Error("GetNodeb() failed for inventoryName=%s: %v", inventoryName, err)
137                 return false
138         }
139         xapp.Logger.Debug("NodeB['%s'] connection status = %d", inventoryName, nodeInfo.ConnectionStatus)
140         return nodeInfo.ConnectionStatus == 1
141 }
142
143 func (e *E2IfState) IsE2ConnectionUp(nbId *string) bool {
144
145         if checkE2State == "false" {
146                 return true
147         }
148
149         if _, ok := e.NbIdMap[*nbId]; ok {
150                 return true
151         } else {
152                 return false
153         }
154 }
155
156 func ExtractNbiIdFromString(s string) (string, error) {
157
158         // Expected string formats are below
159         // gnb_208_092_303030_CONNECTED
160         // gnb_208_092_303030_DISCONNECTED
161         // ...
162
163         var nbId string
164         var err error
165         if strings.Contains(s, "_CONNECTED") {
166                 splitStringTbl := strings.Split(s, "_CONNECTED")
167                 nbId = splitStringTbl[0]
168         } else if strings.Contains(s, "_DISCONNECTED") {
169                 splitStringTbl := strings.Split(s, "_DISCONNECTED")
170                 nbId = splitStringTbl[0]
171         }
172         if len(nbId) == 0 {
173                 return "", fmt.Errorf("ExtractNbiIdFromString(): len(nbId) == 0 ")
174         }
175         return nbId, err
176 }