Changes so that Redis entries will be understood by other xapps.
[scp/ric-app/kpimon.git] / control / control.go
1 package control
2
3 import (
4         "encoding/json"
5         "errors"
6         "log"
7         "os"
8         "strconv"
9         "strings"
10         "sync"
11         "time"
12
13         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
14         "github.com/go-redis/redis"
15 )
16
17 type Control struct {
18         ranList               []string             //nodeB list
19         eventCreateExpired    int32                //maximum time for the RIC Subscription Request event creation procedure in the E2 Node
20         eventDeleteExpired    int32                //maximum time for the RIC Subscription Request event deletion procedure in the E2 Node
21         rcChan                chan *xapp.RMRParams //channel for receiving rmr message
22         client                *redis.Client        //redis client
23         eventCreateExpiredMap map[string]bool      //map for recording the RIC Subscription Request event creation procedure is expired or not
24         eventDeleteExpiredMap map[string]bool      //map for recording the RIC Subscription Request event deletion procedure is expired or not
25         eventCreateExpiredMu  *sync.Mutex          //mutex for eventCreateExpiredMap
26         eventDeleteExpiredMu  *sync.Mutex          //mutex for eventDeleteExpiredMap
27 }
28
29 func init() {
30         file := "/opt/kpimon.log"
31         logFile, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
32         if err != nil {
33                 panic(err)
34         }
35         log.SetOutput(logFile)
36         log.SetPrefix("[qSkipTool]")
37         log.SetFlags(log.LstdFlags | log.Lshortfile | log.LUTC)
38         xapp.Logger.SetLevel(4)
39 }
40
41 func NewControl() Control {
42         str := os.Getenv("ranList")
43         return Control{strings.Split(str, ","),
44                 5, 5,
45                 make(chan *xapp.RMRParams),
46                 redis.NewClient(&redis.Options{
47                         Addr:     os.Getenv("DBAAS_SERVICE_HOST") + ":" + os.Getenv("DBAAS_SERVICE_PORT"), //"localhost:6379"
48                         Password: "",
49                         DB:       0,
50                 }),
51                 make(map[string]bool),
52                 make(map[string]bool),
53                 &sync.Mutex{},
54                 &sync.Mutex{}}
55 }
56
57 func ReadyCB(i interface{}) {
58         c := i.(*Control)
59
60         c.startTimerSubReq()
61         go c.controlLoop()
62 }
63
64 func (c *Control) Run() {
65         _, err := c.client.Ping().Result()
66         if err != nil {
67                 xapp.Logger.Error("Failed to connect to Redis DB with %v", err)
68                 log.Printf("Failed to connect to Redis DB with %v", err)
69         }
70         if len(c.ranList) > 0 {
71                 xapp.SetReadyCB(ReadyCB, c)
72                 xapp.Run(c)
73         } else {
74                 xapp.Logger.Error("gNodeB not set for subscription")
75                 log.Printf("gNodeB not set for subscription")
76         }
77
78 }
79
80 func (c *Control) startTimerSubReq() {
81         timerSR := time.NewTimer(5 * time.Second)
82         count := 0
83
84         go func(t *time.Timer) {
85                 defer timerSR.Stop()
86                 for {
87                         <-t.C
88                         count++
89                         xapp.Logger.Debug("send RIC_SUB_REQ to gNodeB with cnt=%d", count)
90                         log.Printf("send RIC_SUB_REQ to gNodeB with cnt=%d", count)
91                         err := c.sendRicSubRequest(1001, 1001, 0)
92                         if err != nil && count < MAX_SUBSCRIPTION_ATTEMPTS {
93                                 t.Reset(5 * time.Second)
94                         } else {
95                                 break
96                         }
97                 }
98         }(timerSR)
99 }
100
101 func (c *Control) Consume(rp *xapp.RMRParams) (err error) {
102         c.rcChan <- rp
103         return
104 }
105
106 func (c *Control) rmrSend(params *xapp.RMRParams) (err error) {
107         if !xapp.Rmr.Send(params, false) {
108                 err = errors.New("rmr.Send() failed")
109                 xapp.Logger.Error("Failed to rmrSend to %v", err)
110                 log.Printf("Failed to rmrSend to %v", err)
111         }
112         return
113 }
114
115 func (c *Control) rmrReplyToSender(params *xapp.RMRParams) (err error) {
116         if !xapp.Rmr.Send(params, true) {
117                 err = errors.New("rmr.Send() failed")
118                 xapp.Logger.Error("Failed to rmrReplyToSender to %v", err)
119                 log.Printf("Failed to rmrReplyToSender to %v", err)
120         }
121         return
122 }
123
124 func (c *Control) controlLoop() {
125         for {
126                 msg := <-c.rcChan
127                 xapp.Logger.Debug("Received message type: %d", msg.Mtype)
128                 log.Printf("Received message type: %d", msg.Mtype)
129                 switch msg.Mtype {
130                 case 12050:
131                         c.handleIndication(msg)
132                 case 12011:
133                         c.handleSubscriptionResponse(msg)
134                 case 12012:
135                         c.handleSubscriptionFailure(msg)
136                 case 12021:
137                         c.handleSubscriptionDeleteResponse(msg)
138                 case 12022:
139                         c.handleSubscriptionDeleteFailure(msg)
140                 default:
141                         err := errors.New("Message Type " + strconv.Itoa(msg.Mtype) + " is discarded")
142                         xapp.Logger.Error("Unknown message type: %v", err)
143                         log.Printf("Unknown message type: %v", err)
144                 }
145         }
146 }
147
148 func (c *Control) handleIndication(params *xapp.RMRParams) (err error) {
149         var e2ap *E2ap
150         var e2sm *E2sm
151
152         indicationMsg, err := e2ap.GetIndicationMessage(params.Payload)
153         if err != nil {
154                 xapp.Logger.Error("Failed to decode RIC Indication message: %v", err)
155                 log.Printf("Failed to decode RIC Indication message: %v", err)
156                 return
157         }
158
159         log.Printf("RIC Indication message from {%s} received", params.Meid.RanName)
160         log.Printf("RequestID: %d", indicationMsg.RequestID)
161         log.Printf("RequestSequenceNumber: %d", indicationMsg.RequestSequenceNumber)
162         log.Printf("FunctionID: %d", indicationMsg.FuncID)
163         log.Printf("ActionID: %d", indicationMsg.ActionID)
164         log.Printf("IndicationSN: %d", indicationMsg.IndSN)
165         log.Printf("IndicationType: %d", indicationMsg.IndType)
166         log.Printf("IndicationHeader: %x", indicationMsg.IndHeader)
167         log.Printf("IndicationMessage: %x", indicationMsg.IndMessage)
168         log.Printf("CallProcessID: %x", indicationMsg.CallProcessID)
169
170         indicationHdr, err := e2sm.GetIndicationHeader(indicationMsg.IndHeader)
171         if err != nil {
172                 xapp.Logger.Error("Failed to decode RIC Indication Header: %v", err)
173                 log.Printf("Failed to decode RIC Indication Header: %v", err)
174                 return
175         }
176
177         var cellIDHdr string
178         var plmnIDHdr string
179         var sliceIDHdr int32
180         var fiveQIHdr int64
181
182         log.Printf("-----------RIC Indication Header-----------")
183         if indicationHdr.IndHdrType == 1 {
184                 log.Printf("RIC Indication Header Format: %d", indicationHdr.IndHdrType)
185                 indHdrFormat1 := indicationHdr.IndHdr.(*IndicationHeaderFormat1)
186
187                 log.Printf("GlobalKPMnodeIDType: %d", indHdrFormat1.GlobalKPMnodeIDType)
188
189                 if indHdrFormat1.GlobalKPMnodeIDType == 1 {
190                         globalKPMnodegNBID := indHdrFormat1.GlobalKPMnodeID.(*GlobalKPMnodegNBIDType)
191
192                         globalgNBID := globalKPMnodegNBID.GlobalgNBID
193
194                         log.Printf("PlmnID: %x", globalgNBID.PlmnID.Buf)
195                         log.Printf("gNB ID Type: %d", globalgNBID.GnbIDType)
196                         if globalgNBID.GnbIDType == 1 {
197                                 gNBID := globalgNBID.GnbID.(*GNBID)
198                                 log.Printf("gNB ID ID: %x, Unused: %d", gNBID.Buf, gNBID.BitsUnused)
199                         }
200
201                         if globalKPMnodegNBID.GnbCUUPID != nil {
202                                 log.Printf("gNB-CU-UP ID: %x", globalKPMnodegNBID.GnbCUUPID.Buf)
203                         }
204
205                         if globalKPMnodegNBID.GnbDUID != nil {
206                                 log.Printf("gNB-DU ID: %x", globalKPMnodegNBID.GnbDUID.Buf)
207                         }
208                 } else if indHdrFormat1.GlobalKPMnodeIDType == 2 {
209                         globalKPMnodeengNBID := indHdrFormat1.GlobalKPMnodeID.(*GlobalKPMnodeengNBIDType)
210
211                         log.Printf("PlmnID: %x", globalKPMnodeengNBID.PlmnID.Buf)
212                         log.Printf("en-gNB ID Type: %d", globalKPMnodeengNBID.GnbIDType)
213                         if globalKPMnodeengNBID.GnbIDType == 1 {
214                                 engNBID := globalKPMnodeengNBID.GnbID.(*ENGNBID)
215                                 log.Printf("en-gNB ID ID: %x, Unused: %d", engNBID.Buf, engNBID.BitsUnused)
216                         }
217                 } else if indHdrFormat1.GlobalKPMnodeIDType == 3 {
218                         globalKPMnodengeNBID := indHdrFormat1.GlobalKPMnodeID.(*GlobalKPMnodengeNBIDType)
219
220                         log.Printf("PlmnID: %x", globalKPMnodengeNBID.PlmnID.Buf)
221                         log.Printf("ng-eNB ID Type: %d", globalKPMnodengeNBID.EnbIDType)
222                         if globalKPMnodengeNBID.EnbIDType == 1 {
223                                 ngeNBID := globalKPMnodengeNBID.EnbID.(*NGENBID_Macro)
224                                 log.Printf("ng-eNB ID ID: %x, Unused: %d", ngeNBID.Buf, ngeNBID.BitsUnused)
225                         } else if globalKPMnodengeNBID.EnbIDType == 2 {
226                                 ngeNBID := globalKPMnodengeNBID.EnbID.(*NGENBID_ShortMacro)
227                                 log.Printf("ng-eNB ID ID: %x, Unused: %d", ngeNBID.Buf, ngeNBID.BitsUnused)
228                         } else if globalKPMnodengeNBID.EnbIDType == 3 {
229                                 ngeNBID := globalKPMnodengeNBID.EnbID.(*NGENBID_LongMacro)
230                                 log.Printf("ng-eNB ID ID: %x, Unused: %d", ngeNBID.Buf, ngeNBID.BitsUnused)
231                         }
232                 } else if indHdrFormat1.GlobalKPMnodeIDType == 4 {
233                         globalKPMnodeeNBID := indHdrFormat1.GlobalKPMnodeID.(*GlobalKPMnodeeNBIDType)
234
235                         log.Printf("PlmnID: %x", globalKPMnodeeNBID.PlmnID.Buf)
236                         log.Printf("eNB ID Type: %d", globalKPMnodeeNBID.EnbIDType)
237                         if globalKPMnodeeNBID.EnbIDType == 1 {
238                                 eNBID := globalKPMnodeeNBID.EnbID.(*ENBID_Macro)
239                                 log.Printf("eNB ID ID: %x, Unused: %d", eNBID.Buf, eNBID.BitsUnused)
240                         } else if globalKPMnodeeNBID.EnbIDType == 2 {
241                                 eNBID := globalKPMnodeeNBID.EnbID.(*ENBID_Home)
242                                 log.Printf("eNB ID ID: %x, Unused: %d", eNBID.Buf, eNBID.BitsUnused)
243                         } else if globalKPMnodeeNBID.EnbIDType == 3 {
244                                 eNBID := globalKPMnodeeNBID.EnbID.(*ENBID_ShortMacro)
245                                 log.Printf("eNB ID ID: %x, Unused: %d", eNBID.Buf, eNBID.BitsUnused)
246                         } else if globalKPMnodeeNBID.EnbIDType == 4 {
247                                 eNBID := globalKPMnodeeNBID.EnbID.(*ENBID_LongMacro)
248                                 log.Printf("eNB ID ID: %x, Unused: %d", eNBID.Buf, eNBID.BitsUnused)
249                         }
250
251                 }
252
253                 if indHdrFormat1.NRCGI != nil {
254
255                         log.Printf("nRCGI.PlmnID: %x", indHdrFormat1.NRCGI.PlmnID.Buf)
256                         log.Printf("nRCGI.NRCellID ID: %x, Unused: %d", indHdrFormat1.NRCGI.NRCellID.Buf, indHdrFormat1.NRCGI.NRCellID.BitsUnused)
257
258                         cellIDHdr, err = e2sm.ParseNRCGI(*indHdrFormat1.NRCGI)
259                         if err != nil {
260                                 xapp.Logger.Error("Failed to parse NRCGI in RIC Indication Header: %v", err)
261                                 log.Printf("Failed to parse NRCGI in RIC Indication Header: %v", err)
262                                 return
263                         }
264                 } else {
265                         cellIDHdr = ""
266                 }
267
268                 if indHdrFormat1.PlmnID != nil {
269                         log.Printf("PlmnID: %x", indHdrFormat1.PlmnID.Buf)
270
271                         plmnIDHdr, err = e2sm.ParsePLMNIdentity(indHdrFormat1.PlmnID.Buf, indHdrFormat1.PlmnID.Size)
272                         if err != nil {
273                                 xapp.Logger.Error("Failed to parse PlmnID in RIC Indication Header: %v", err)
274                                 log.Printf("Failed to parse PlmnID in RIC Indication Header: %v", err)
275                                 return
276                         }
277                 } else {
278                         plmnIDHdr = ""
279                 }
280
281                 if indHdrFormat1.SliceID != nil {
282                         log.Printf("SST: %x", indHdrFormat1.SliceID.SST.Buf)
283
284                         if indHdrFormat1.SliceID.SD != nil {
285                                 log.Printf("SD: %x", indHdrFormat1.SliceID.SD.Buf)
286                         }
287
288                         sliceIDHdr, err = e2sm.ParseSliceID(*indHdrFormat1.SliceID)
289                         if err != nil {
290                                 xapp.Logger.Error("Failed to parse SliceID in RIC Indication Header: %v", err)
291                                 log.Printf("Failed to parse SliceID in RIC Indication Header: %v", err)
292                                 return
293                         }
294                 } else {
295                         sliceIDHdr = -1
296                 }
297
298                 if indHdrFormat1.FiveQI != -1 {
299                         log.Printf("5QI: %d", indHdrFormat1.FiveQI)
300                 }
301                 fiveQIHdr = indHdrFormat1.FiveQI
302
303                 if indHdrFormat1.Qci != -1 {
304                         log.Printf("QCI: %d", indHdrFormat1.Qci)
305                 }
306
307                 if indHdrFormat1.UeMessageType != -1 {
308                         log.Printf("Ue Report type: %d", indHdrFormat1.UeMessageType)
309                 }
310
311                 if indHdrFormat1.GnbDUID != nil {
312                         log.Printf("gNB-DU-ID: %x", indHdrFormat1.GnbDUID.Buf)
313                 }
314
315                 if indHdrFormat1.GnbNameType == 1 {
316                         log.Printf("gNB-DU-Name: %x", (indHdrFormat1.GnbName.(*GNB_DU_Name)).Buf)
317                 } else if indHdrFormat1.GnbNameType == 2 {
318                         log.Printf("gNB-CU-CP-Name: %x", (indHdrFormat1.GnbName.(*GNB_CU_CP_Name)).Buf)
319                 } else if indHdrFormat1.GnbNameType == 3 {
320                         log.Printf("gNB-CU-UP-Name: %x", (indHdrFormat1.GnbName.(*GNB_CU_UP_Name)).Buf)
321                 }
322
323                 if indHdrFormat1.GlobalgNBID != nil {
324                         log.Printf("PlmnID: %x", indHdrFormat1.GlobalgNBID.PlmnID.Buf)
325                         log.Printf("gNB ID Type: %d", indHdrFormat1.GlobalgNBID.GnbIDType)
326                         if indHdrFormat1.GlobalgNBID.GnbIDType == 1 {
327                                 gNBID := indHdrFormat1.GlobalgNBID.GnbID.(*GNBID)
328                                 log.Printf("gNB ID ID: %x, Unused: %d", gNBID.Buf, gNBID.BitsUnused)
329                         }
330                 }
331
332         } else {
333                 xapp.Logger.Error("Unknown RIC Indication Header Format: %d", indicationHdr.IndHdrType)
334                 log.Printf("Unknown RIC Indication Header Format: %d", indicationHdr.IndHdrType)
335                 return
336         }
337
338         indMsg, err := e2sm.GetIndicationMessage(indicationMsg.IndMessage)
339         if err != nil {
340                 xapp.Logger.Error("Failed to decode RIC Indication Message: %v", err)
341                 log.Printf("Failed to decode RIC Indication Message: %v", err)
342                 return
343         }
344
345         var flag bool
346         var containerType int32
347         var timestampPDCPBytes *Timestamp
348         var dlPDCPBytes int64
349         var ulPDCPBytes int64
350         var timestampPRB *Timestamp
351         var availPRBDL int64
352         var availPRBUL int64
353
354         log.Printf("-----------RIC Indication Message-----------")
355         log.Printf("StyleType: %d", indMsg.StyleType)
356         if indMsg.IndMsgType == 1 {
357                 log.Printf("RIC Indication Message Format: %d", indMsg.IndMsgType)
358
359                 indMsgFormat1 := indMsg.IndMsg.(*IndicationMessageFormat1)
360
361                 log.Printf("PMContainerCount: %d", indMsgFormat1.PMContainerCount)
362
363                 for i := 0; i < indMsgFormat1.PMContainerCount; i++ {
364                         flag = false
365                         timestampPDCPBytes = nil
366                         dlPDCPBytes = -1
367                         ulPDCPBytes = -1
368                         timestampPRB = nil
369                         availPRBDL = -1
370                         availPRBUL = -1
371
372                         log.Printf("PMContainer[%d]: ", i)
373
374                         pmContainer := indMsgFormat1.PMContainers[i]
375
376                         if pmContainer.PFContainer != nil {
377                                 containerType = pmContainer.PFContainer.ContainerType
378
379                                 log.Printf("PFContainerType: %d", containerType)
380
381                                 if containerType == 1 {
382                                         log.Printf("oDU PF Container: ")
383
384                                         oDU := pmContainer.PFContainer.Container.(*ODUPFContainerType)
385
386                                         cellResourceReportCount := oDU.CellResourceReportCount
387                                         log.Printf("CellResourceReportCount: %d", cellResourceReportCount)
388
389                                         for j := 0; j < cellResourceReportCount; j++ {
390                                                 log.Printf("CellResourceReport[%d]: ", j)
391
392                                                 cellResourceReport := oDU.CellResourceReports[j]
393
394                                                 log.Printf("nRCGI.PlmnID: %x", cellResourceReport.NRCGI.PlmnID.Buf)
395                                                 log.Printf("nRCGI.nRCellID: %x", cellResourceReport.NRCGI.NRCellID.Buf)
396
397                                                 cellID, err := e2sm.ParseNRCGI(cellResourceReport.NRCGI)
398                                                 if err != nil {
399                                                         xapp.Logger.Error("Failed to parse CellID in DU PF Container: %v", err)
400                                                         log.Printf("Failed to parse CellID in DU PF Container: %v", err)
401                                                         continue
402                                                 }
403                                                 if cellID == cellIDHdr {
404                                                         flag = true
405                                                 }
406
407                                                 log.Printf("TotalofAvailablePRBsDL: %d", cellResourceReport.TotalofAvailablePRBs.DL)
408                                                 log.Printf("TotalofAvailablePRBsUL: %d", cellResourceReport.TotalofAvailablePRBs.UL)
409
410                                                 if flag {
411                                                         availPRBDL = cellResourceReport.TotalofAvailablePRBs.DL
412                                                         availPRBUL = cellResourceReport.TotalofAvailablePRBs.UL
413                                                 }
414
415                                                 servedPlmnPerCellCount := cellResourceReport.ServedPlmnPerCellCount
416                                                 log.Printf("ServedPlmnPerCellCount: %d", servedPlmnPerCellCount)
417
418                                                 for k := 0; k < servedPlmnPerCellCount; k++ {
419                                                         log.Printf("ServedPlmnPerCell[%d]: ", k)
420
421                                                         servedPlmnPerCell := cellResourceReport.ServedPlmnPerCells[k]
422
423                                                         log.Printf("PlmnID: %x", servedPlmnPerCell.PlmnID.Buf)
424
425                                                         if servedPlmnPerCell.DUPM5GC != nil {
426                                                                 slicePerPlmnPerCellCount := servedPlmnPerCell.DUPM5GC.SlicePerPlmnPerCellCount
427                                                                 log.Printf("SlicePerPlmnPerCellCount: %d", slicePerPlmnPerCellCount)
428
429                                                                 for l := 0; l < slicePerPlmnPerCellCount; l++ {
430                                                                         log.Printf("SlicePerPlmnPerCell[%d]: ", l)
431
432                                                                         slicePerPlmnPerCell := servedPlmnPerCell.DUPM5GC.SlicePerPlmnPerCells[l]
433
434                                                                         log.Printf("SliceID.sST: %x", slicePerPlmnPerCell.SliceID.SST.Buf)
435                                                                         if slicePerPlmnPerCell.SliceID.SD != nil {
436                                                                                 log.Printf("SliceID.sD: %x", slicePerPlmnPerCell.SliceID.SD.Buf)
437                                                                         }
438
439                                                                         fQIPERSlicesPerPlmnPerCellCount := slicePerPlmnPerCell.FQIPERSlicesPerPlmnPerCellCount
440                                                                         log.Printf("5QIPerSlicesPerPlmnPerCellCount: %d", fQIPERSlicesPerPlmnPerCellCount)
441
442                                                                         for m := 0; m < fQIPERSlicesPerPlmnPerCellCount; m++ {
443                                                                                 log.Printf("5QIPerSlicesPerPlmnPerCell[%d]: ", m)
444
445                                                                                 fQIPERSlicesPerPlmnPerCell := slicePerPlmnPerCell.FQIPERSlicesPerPlmnPerCells[m]
446
447                                                                                 log.Printf("5QI: %d", fQIPERSlicesPerPlmnPerCell.FiveQI)
448                                                                                 log.Printf("PrbUsageDL: %d", fQIPERSlicesPerPlmnPerCell.PrbUsage.DL)
449                                                                                 log.Printf("PrbUsageUL: %d", fQIPERSlicesPerPlmnPerCell.PrbUsage.UL)
450                                                                         }
451                                                                 }
452                                                         }
453
454                                                         if servedPlmnPerCell.DUPMEPC != nil {
455                                                                 perQCIReportCount := servedPlmnPerCell.DUPMEPC.PerQCIReportCount
456                                                                 log.Printf("PerQCIReportCount: %d", perQCIReportCount)
457
458                                                                 for l := 0; l < perQCIReportCount; l++ {
459                                                                         log.Printf("PerQCIReports[%d]: ", l)
460
461                                                                         perQCIReport := servedPlmnPerCell.DUPMEPC.PerQCIReports[l]
462
463                                                                         log.Printf("QCI: %d", perQCIReport.QCI)
464                                                                         log.Printf("PrbUsageDL: %d", perQCIReport.PrbUsage.DL)
465                                                                         log.Printf("PrbUsageUL: %d", perQCIReport.PrbUsage.UL)
466                                                                 }
467                                                         }
468                                                 }
469                                         }
470                                 } else if containerType == 2 {
471                                         log.Printf("oCU-CP PF Container: ")
472
473                                         oCUCP := pmContainer.PFContainer.Container.(*OCUCPPFContainerType)
474
475                                         if oCUCP.GNBCUCPName != nil {
476                                                 log.Printf("gNB-CU-CP Name: %x", oCUCP.GNBCUCPName.Buf)
477                                         }
478
479                                         log.Printf("NumberOfActiveUEs: %d", oCUCP.CUCPResourceStatus.NumberOfActiveUEs)
480                                 } else if containerType == 3 {
481                                         log.Printf("oCU-UP PF Container: ")
482
483                                         oCUUP := pmContainer.PFContainer.Container.(*OCUUPPFContainerType)
484
485                                         if oCUUP.GNBCUUPName != nil {
486                                                 log.Printf("gNB-CU-UP Name: %x", oCUUP.GNBCUUPName.Buf)
487                                         }
488
489                                         cuUPPFContainerItemCount := oCUUP.CUUPPFContainerItemCount
490                                         log.Printf("CU-UP PF Container Item Count: %d", cuUPPFContainerItemCount)
491
492                                         for j := 0; j < cuUPPFContainerItemCount; j++ {
493                                                 log.Printf("CU-UP PF Container Item [%d]: ", j)
494
495                                                 cuUPPFContainerItem := oCUUP.CUUPPFContainerItems[j]
496
497                                                 log.Printf("InterfaceType: %d", cuUPPFContainerItem.InterfaceType)
498
499                                                 cuUPPlmnCount := cuUPPFContainerItem.OCUUPPMContainer.CUUPPlmnCount
500                                                 log.Printf("CU-UP Plmn Count: %d", cuUPPlmnCount)
501
502                                                 for k := 0; k < cuUPPlmnCount; k++ {
503                                                         log.Printf("CU-UP Plmn [%d]: ", k)
504
505                                                         cuUPPlmn := cuUPPFContainerItem.OCUUPPMContainer.CUUPPlmns[k]
506
507                                                         log.Printf("PlmnID: %x", cuUPPlmn.PlmnID.Buf)
508
509                                                         plmnID, err := e2sm.ParsePLMNIdentity(cuUPPlmn.PlmnID.Buf, cuUPPlmn.PlmnID.Size)
510                                                         if err != nil {
511                                                                 xapp.Logger.Error("Failed to parse PlmnID in CU-UP PF Container: %v", err)
512                                                                 log.Printf("Failed to parse PlmnID in CU-UP PF Container: %v", err)
513                                                                 continue
514                                                         }
515
516                                                         if cuUPPlmn.CUUPPM5GC != nil {
517                                                                 sliceToReportCount := cuUPPlmn.CUUPPM5GC.SliceToReportCount
518                                                                 log.Printf("SliceToReportCount: %d", sliceToReportCount)
519
520                                                                 for l := 0; l < sliceToReportCount; l++ {
521                                                                         log.Printf("SliceToReport[%d]: ", l)
522
523                                                                         sliceToReport := cuUPPlmn.CUUPPM5GC.SliceToReports[l]
524
525                                                                         log.Printf("SliceID.sST: %x", sliceToReport.SliceID.SST.Buf)
526                                                                         if sliceToReport.SliceID.SD != nil {
527                                                                                 log.Printf("SliceID.sD: %x", sliceToReport.SliceID.SD.Buf)
528                                                                         }
529
530                                                                         sliceID, err := e2sm.ParseSliceID(sliceToReport.SliceID)
531                                                                         if err != nil {
532                                                                                 xapp.Logger.Error("Failed to parse sliceID in CU-UP PF Container with PlmnID [%s]: %v", plmnID, err)
533                                                                                 log.Printf("Failed to parse sliceID in CU-UP PF Container with PlmnID [%s]: %v", plmnID, err)
534                                                                                 continue
535                                                                         }
536
537                                                                         fQIPERSlicesPerPlmnCount := sliceToReport.FQIPERSlicesPerPlmnCount
538                                                                         log.Printf("5QIPerSlicesPerPlmnCount: %d", fQIPERSlicesPerPlmnCount)
539
540                                                                         for m := 0; m < fQIPERSlicesPerPlmnCount; m++ {
541                                                                                 log.Printf("5QIPerSlicesPerPlmn[%d]: ", m)
542
543                                                                                 fQIPERSlicesPerPlmn := sliceToReport.FQIPERSlicesPerPlmns[m]
544
545                                                                                 fiveQI := fQIPERSlicesPerPlmn.FiveQI
546                                                                                 log.Printf("5QI: %d", fiveQI)
547
548                                                                                 if plmnID == plmnIDHdr && sliceID == sliceIDHdr && fiveQI == fiveQIHdr {
549                                                                                         flag = true
550                                                                                 }
551
552                                                                                 if fQIPERSlicesPerPlmn.PDCPBytesDL != nil {
553                                                                                         log.Printf("PDCPBytesDL: %x", fQIPERSlicesPerPlmn.PDCPBytesDL.Buf)
554
555                                                                                         if flag {
556                                                                                                 dlPDCPBytes, err = e2sm.ParseInteger(fQIPERSlicesPerPlmn.PDCPBytesDL.Buf, fQIPERSlicesPerPlmn.PDCPBytesDL.Size)
557                                                                                                 if err != nil {
558                                                                                                         xapp.Logger.Error("Failed to parse PDCPBytesDL in CU-UP PF Container with PlmnID [%s], SliceID [%d], 5QI [%d]: %v", plmnID, sliceID, fiveQI, err)
559                                                                                                         log.Printf("Failed to parse PDCPBytesDL in CU-UP PF Container with PlmnID [%s], SliceID [%d], 5QI [%d]: %v", plmnID, sliceID, fiveQI, err)
560                                                                                                         continue
561                                                                                                 }
562                                                                                         }
563                                                                                 }
564
565                                                                                 if fQIPERSlicesPerPlmn.PDCPBytesUL != nil {
566                                                                                         log.Printf("PDCPBytesUL: %x", fQIPERSlicesPerPlmn.PDCPBytesUL.Buf)
567
568                                                                                         if flag {
569                                                                                                 ulPDCPBytes, err = e2sm.ParseInteger(fQIPERSlicesPerPlmn.PDCPBytesUL.Buf, fQIPERSlicesPerPlmn.PDCPBytesUL.Size)
570                                                                                                 if err != nil {
571                                                                                                         xapp.Logger.Error("Failed to parse PDCPBytesUL in CU-UP PF Container with PlmnID [%s], SliceID [%d], 5QI [%d]: %v", plmnID, sliceID, fiveQI, err)
572                                                                                                         log.Printf("Failed to parse PDCPBytesUL in CU-UP PF Container with PlmnID [%s], SliceID [%d], 5QI [%d]: %v", plmnID, sliceID, fiveQI, err)
573                                                                                                         continue
574                                                                                                 }
575                                                                                         }
576                                                                                 }
577                                                                         }
578                                                                 }
579                                                         }
580
581                                                         if cuUPPlmn.CUUPPMEPC != nil {
582                                                                 cuUPPMEPCPerQCIReportCount := cuUPPlmn.CUUPPMEPC.CUUPPMEPCPerQCIReportCount
583                                                                 log.Printf("PerQCIReportCount: %d", cuUPPMEPCPerQCIReportCount)
584
585                                                                 for l := 0; l < cuUPPMEPCPerQCIReportCount; l++ {
586                                                                         log.Printf("PerQCIReport[%d]: ", l)
587
588                                                                         cuUPPMEPCPerQCIReport := cuUPPlmn.CUUPPMEPC.CUUPPMEPCPerQCIReports[l]
589
590                                                                         log.Printf("QCI: %d", cuUPPMEPCPerQCIReport.QCI)
591
592                                                                         if cuUPPMEPCPerQCIReport.PDCPBytesDL != nil {
593                                                                                 log.Printf("PDCPBytesDL: %x", cuUPPMEPCPerQCIReport.PDCPBytesDL.Buf)
594                                                                         }
595                                                                         if cuUPPMEPCPerQCIReport.PDCPBytesUL != nil {
596                                                                                 log.Printf("PDCPBytesUL: %x", cuUPPMEPCPerQCIReport.PDCPBytesUL.Buf)
597                                                                         }
598                                                                 }
599                                                         }
600                                                 }
601                                         }
602                                 } else {
603                                         xapp.Logger.Error("Unknown PF Container type: %d", containerType)
604                                         log.Printf("Unknown PF Container type: %d", containerType)
605                                         continue
606                                 }
607                         }
608
609                         if pmContainer.RANContainer != nil {
610                                 log.Printf("RANContainer: %x", pmContainer.RANContainer.Timestamp.Buf)
611
612                                 timestamp, _ := e2sm.ParseTimestamp(pmContainer.RANContainer.Timestamp.Buf, pmContainer.RANContainer.Timestamp.Size)
613                                 log.Printf("Timestamp=[sec: %d, nsec: %d]", timestamp.TVsec, timestamp.TVnsec)
614
615                                 containerType = pmContainer.RANContainer.ContainerType
616                                 if containerType == 1 {
617                                         log.Printf("DU Usage Report: ")
618
619                                         oDUUE := pmContainer.RANContainer.Container.(*DUUsageReportType)
620
621                                         for j := 0; j < oDUUE.CellResourceReportItemCount; j++ {
622                                                 cellResourceReportItem := oDUUE.CellResourceReportItems[j]
623
624                                                 log.Printf("nRCGI.PlmnID: %x", cellResourceReportItem.NRCGI.PlmnID.Buf)
625                                                 log.Printf("nRCGI.NRCellID: %x, Unused: %d", cellResourceReportItem.NRCGI.NRCellID.Buf, cellResourceReportItem.NRCGI.NRCellID.BitsUnused)
626
627                                                 servingCellID, err := e2sm.ParseNRCGI(cellResourceReportItem.NRCGI)
628                                                 if err != nil {
629                                                         xapp.Logger.Error("Failed to parse NRCGI in DU Usage Report: %v", err)
630                                                         log.Printf("Failed to parse NRCGI in DU Usage Report: %v", err)
631                                                         continue
632                                                 }
633
634                                                 for k := 0; k < cellResourceReportItem.UeResourceReportItemCount; k++ {
635                                                         ueResourceReportItem := cellResourceReportItem.UeResourceReportItems[k]
636
637                                                         log.Printf("C-RNTI: %x", ueResourceReportItem.CRNTI.Buf)
638
639                                                         ueID, err := e2sm.ParseInteger(ueResourceReportItem.CRNTI.Buf, ueResourceReportItem.CRNTI.Size)
640                                                         if err != nil {
641                                                                 xapp.Logger.Error("Failed to parse C-RNTI in DU Usage Report with Serving Cell ID [%s]: %v", servingCellID, err)
642                                                                 log.Printf("Failed to parse C-RNTI in DU Usage Report with Serving Cell ID [%s]: %v", servingCellID, err)
643                                                                 continue
644                                                         }
645
646                                                         var ueMetrics UeMetricsEntry
647                                                         if isUeExist, _ := c.client.Exists("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10)).Result(); isUeExist == 1 {
648                                                                 ueJsonStr, _ := c.client.Get("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10)).Result()
649                                                                 json.Unmarshal([]byte(ueJsonStr), &ueMetrics)
650                                                         }
651
652                                                         ueMetrics.UeID = ueID
653                                                         log.Printf("UeID: %d", ueMetrics.UeID)
654                                                         ueMetrics.ServingCellID = servingCellID                                                 
655                                                         log.Printf("ServingCellID: %s", ueMetrics.ServingCellID)
656                                                         ueMetrics.MeasPeriodRF = 20
657
658                                                         if flag {
659                                                                 timestampPRB = timestamp
660                                                         }
661
662                                                         ueMetrics.MeasTimestampPRB.TVsec = timestamp.TVsec
663                                                         ueMetrics.MeasTimestampPRB.TVnsec = timestamp.TVnsec
664
665                                                         if ueResourceReportItem.PRBUsageDL != -1 {
666                                                                 ueMetrics.PRBUsageDL = ueResourceReportItem.PRBUsageDL
667                                                                 log.Printf("PRBUsageDL: %d", ueMetrics.PRBUsageDL)
668                                                         }
669
670                                                         if ueResourceReportItem.PRBUsageUL != -1 {
671                                                                 ueMetrics.PRBUsageUL = ueResourceReportItem.PRBUsageUL
672                                                                 log.Printf("PRBUsageUL: %d", ueMetrics.PRBUsageUL)
673                                                         }
674
675                                                         newUeJsonStr, err := json.Marshal(&ueMetrics)
676                                                         if err != nil {
677                                                                 xapp.Logger.Error("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
678                                                                 log.Printf("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
679                                                                 continue
680                                                         }
681                                                         err = c.client.Set("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10), newUeJsonStr, 0).Err()
682                                                         if err != nil {
683                                                                 xapp.Logger.Error("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
684                                                                 log.Printf("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
685                                                                 continue
686                                                         }
687                                                 }
688                                         }
689                                 } else if containerType == 2 {
690                                         log.Printf("CU-CP Usage Report: ")
691
692                                         oCUCPUE := pmContainer.RANContainer.Container.(*CUCPUsageReportType)
693
694                                         for j := 0; j < oCUCPUE.CellResourceReportItemCount; j++ {
695                                                 cellResourceReportItem := oCUCPUE.CellResourceReportItems[j]
696
697                                                 log.Printf("nRCGI.PlmnID: %x", cellResourceReportItem.NRCGI.PlmnID.Buf)
698                                                 log.Printf("nRCGI.NRCellID: %x, Unused: %d", cellResourceReportItem.NRCGI.NRCellID.Buf, cellResourceReportItem.NRCGI.NRCellID.BitsUnused)
699
700                                                 servingCellID, err := e2sm.ParseNRCGI(cellResourceReportItem.NRCGI)
701                                                 if err != nil {
702                                                         xapp.Logger.Error("Failed to parse NRCGI in CU-CP Usage Report: %v", err)
703                                                         log.Printf("Failed to parse NRCGI in CU-CP Usage Report: %v", err)
704                                                         continue
705                                                 }
706
707                                                 for k := 0; k < cellResourceReportItem.UeResourceReportItemCount; k++ {
708                                                         ueResourceReportItem := cellResourceReportItem.UeResourceReportItems[k]
709
710                                                         log.Printf("C-RNTI: %x", ueResourceReportItem.CRNTI.Buf)
711
712                                                         ueID, err := e2sm.ParseInteger(ueResourceReportItem.CRNTI.Buf, ueResourceReportItem.CRNTI.Size)
713                                                         if err != nil {
714                                                                 xapp.Logger.Error("Failed to parse C-RNTI in CU-CP Usage Report with Serving Cell ID [%s]: %v", err)
715                                                                 log.Printf("Failed to parse C-RNTI in CU-CP Usage Report with Serving Cell ID [%s]: %v", err)
716                                                                 continue
717                                                         }
718
719                                                         var ueMetrics UeMetricsEntry
720                                                         if isUeExist, _ := c.client.Exists("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10)).Result(); isUeExist == 1 {
721                                                                 ueJsonStr, _ := c.client.Get("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10)).Result()
722                                                                 json.Unmarshal([]byte(ueJsonStr), &ueMetrics)
723                                                         }
724
725                                                         ueMetrics.UeID = ueID
726                                                         log.Printf("UeID: %d", ueMetrics.UeID)
727                                                         ueMetrics.ServingCellID = servingCellID
728                                                         log.Printf("ServingCellID: %s", ueMetrics.ServingCellID)
729
730                                                         ueMetrics.MeasTimeRF.TVsec = timestamp.TVsec
731                                                         ueMetrics.MeasTimeRF.TVnsec = timestamp.TVnsec
732
733                                                         ueMetrics.MeasPeriodPDCP = 20
734                                                         ueMetrics.MeasPeriodPRB = 20
735
736                                                         if ueResourceReportItem.ServingCellRF != nil {
737                                                                 err = json.Unmarshal(ueResourceReportItem.ServingCellRF.Buf, &ueMetrics.ServingCellRF)
738                                                                 log.Printf("ueMetrics.ServingCellRF: %+v", ueMetrics.ServingCellRF)
739                                                                 if err != nil {
740                                                                         xapp.Logger.Error("Failed to Unmarshal ServingCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
741                                                                         log.Printf("Failed to Unmarshal ServingCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
742                                                                         log.Printf("ServingCellRF raw data: %x", ueResourceReportItem.ServingCellRF.Buf)
743                                                                         continue
744                                                                 }
745                                                         }
746
747                                                         if ueResourceReportItem.NeighborCellRF != nil {
748                                                                 err = json.Unmarshal(ueResourceReportItem.NeighborCellRF.Buf, &ueMetrics.NeighborCellsRF)
749                                                                 log.Printf("ueMetrics.NeighborCellsRF: %+v", ueMetrics.NeighborCellsRF)
750                                                                 if err != nil {
751                                                                         xapp.Logger.Error("Failed to Unmarshal NeighborCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
752                                                                         log.Printf("Failed to Unmarshal NeighborCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
753                                                                         log.Printf("NeighborCellRF raw data: %x", ueResourceReportItem.NeighborCellRF.Buf)
754                                                                         continue
755                                                                 }
756                                                         }
757
758                                                         newUeJsonStr, err := json.Marshal(&ueMetrics)
759                                                         if err != nil {
760                                                                 xapp.Logger.Error("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
761                                                                 log.Printf("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
762                                                                 continue
763                                                         }
764                                                         err = c.client.Set("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10), newUeJsonStr, 0).Err()
765                                                         if err != nil {
766                                                                 xapp.Logger.Error("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
767                                                                 log.Printf("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
768                                                                 continue
769                                                         }
770                                                 }
771                                         }
772                                 } else if containerType == 3 {
773                                         log.Printf("CU-UP Usage Report: ")
774
775                                         oCUUPUE := pmContainer.RANContainer.Container.(*CUUPUsageReportType)
776
777                                         for j := 0; j < oCUUPUE.CellResourceReportItemCount; j++ {
778                                                 cellResourceReportItem := oCUUPUE.CellResourceReportItems[j]
779
780                                                 log.Printf("nRCGI.PlmnID: %x", cellResourceReportItem.NRCGI.PlmnID.Buf)
781                                                 log.Printf("nRCGI.NRCellID: %x, Unused: %d", cellResourceReportItem.NRCGI.NRCellID.Buf, cellResourceReportItem.NRCGI.NRCellID.BitsUnused)
782
783                                                 servingCellID, err := e2sm.ParseNRCGI(cellResourceReportItem.NRCGI)
784                                                 if err != nil {
785                                                         xapp.Logger.Error("Failed to parse NRCGI in CU-UP Usage Report: %v", err)
786                                                         log.Printf("Failed to parse NRCGI in CU-UP Usage Report: %v", err)
787                                                         continue
788                                                 }
789
790                                                 for k := 0; k < cellResourceReportItem.UeResourceReportItemCount; k++ {
791                                                         ueResourceReportItem := cellResourceReportItem.UeResourceReportItems[k]
792
793                                                         log.Printf("C-RNTI: %x", ueResourceReportItem.CRNTI.Buf)
794
795                                                         ueID, err := e2sm.ParseInteger(ueResourceReportItem.CRNTI.Buf, ueResourceReportItem.CRNTI.Size)
796                                                         if err != nil {
797                                                                 xapp.Logger.Error("Failed to parse C-RNTI in CU-UP Usage Report Serving Cell ID [%s]: %v", servingCellID, err)
798                                                                 log.Printf("Failed to parse C-RNTI in CU-UP Usage Report Serving Cell ID [%s]: %v", servingCellID, err)
799                                                                 continue
800                                                         }
801
802                                                         var ueMetrics UeMetricsEntry
803                                                         if isUeExist, _ := c.client.Exists("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10)).Result(); isUeExist == 1 {
804                                                                 ueJsonStr, _ := c.client.Get("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10)).Result()
805                                                                 json.Unmarshal([]byte(ueJsonStr), &ueMetrics)
806                                                         }
807
808                                                         ueMetrics.UeID = ueID
809                                                         log.Printf("UeID: %d", ueMetrics.UeID)
810                                                         ueMetrics.ServingCellID = servingCellID
811                                                         log.Printf("ServingCellID: %s", ueMetrics.ServingCellID)
812
813                                                         if flag {
814                                                                 timestampPDCPBytes = timestamp
815                                                         }
816
817                                                         ueMetrics.MeasTimestampPDCPBytes.TVsec = timestamp.TVsec
818                                                         ueMetrics.MeasTimestampPDCPBytes.TVnsec = timestamp.TVnsec
819
820                                                         if ueResourceReportItem.PDCPBytesDL != nil {
821                                                                 ueMetrics.PDCPBytesDL, err = e2sm.ParseInteger(ueResourceReportItem.PDCPBytesDL.Buf, ueResourceReportItem.PDCPBytesDL.Size)
822                                                                 if err != nil {
823                                                                         xapp.Logger.Error("Failed to parse PDCPBytesDL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
824                                                                         log.Printf("Failed to parse PDCPBytesDL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
825                                                                         continue
826                                                                 }
827                                                         }
828
829                                                         if ueResourceReportItem.PDCPBytesUL != nil {
830                                                                 ueMetrics.PDCPBytesUL, err = e2sm.ParseInteger(ueResourceReportItem.PDCPBytesUL.Buf, ueResourceReportItem.PDCPBytesUL.Size)
831                                                                 if err != nil {
832                                                                         xapp.Logger.Error("Failed to parse PDCPBytesUL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
833                                                                         log.Printf("Failed to parse PDCPBytesUL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
834                                                                         continue
835                                                                 }
836                                                         }
837
838                                                         newUeJsonStr, err := json.Marshal(&ueMetrics)
839                                                         if err != nil {
840                                                                 xapp.Logger.Error("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
841                                                                 log.Printf("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
842                                                                 continue
843                                                         }
844                                                         err = c.client.Set("{TS-UE-metrics}," + strconv.FormatInt(ueID, 10), newUeJsonStr, 0).Err()
845                                                         if err != nil {
846                                                                 xapp.Logger.Error("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
847                                                                 log.Printf("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
848                                                                 continue
849                                                         }
850                                                 }
851                                         }
852                                 } else {
853                                         xapp.Logger.Error("Unknown PF Container Type: %d", containerType)
854                                         log.Printf("Unknown PF Container Type: %d", containerType)
855                                         continue
856                                 }
857                         }
858
859                         if flag {
860                                 var cellMetrics CellMetricsEntry
861                                 if isCellExist, _ := c.client.Exists("{TS-cell-metrics}," + cellIDHdr).Result(); isCellExist == 1 {
862                                         cellJsonStr, _ := c.client.Get("{TS-cell-metrics}," + cellIDHdr).Result()
863                                         json.Unmarshal([]byte(cellJsonStr), &cellMetrics)
864                                 }
865
866                                 cellMetrics.MeasPeriodPDCP = 20
867                                 cellMetrics.MeasPeriodPRB = 20
868                                 cellMetrics.CellID = cellIDHdr
869
870                                 if timestampPDCPBytes != nil {
871                                         cellMetrics.MeasTimestampPDCPBytes.TVsec = timestampPDCPBytes.TVsec
872                                         cellMetrics.MeasTimestampPDCPBytes.TVnsec = timestampPDCPBytes.TVnsec
873                                 }
874                                 if dlPDCPBytes != -1 {
875                                         cellMetrics.PDCPBytesDL = dlPDCPBytes
876                                 }
877                                 if ulPDCPBytes != -1 {
878                                         cellMetrics.PDCPBytesUL = ulPDCPBytes
879                                 }
880                                 if timestampPRB != nil {
881                                         cellMetrics.MeasTimestampPRB.TVsec = timestampPRB.TVsec
882                                         cellMetrics.MeasTimestampPRB.TVnsec = timestampPRB.TVnsec
883                                 }
884                                 if availPRBDL != -1 {
885                                         cellMetrics.AvailPRBDL = availPRBDL
886                                 }
887                                 if availPRBUL != -1 {
888                                         cellMetrics.AvailPRBUL = availPRBUL
889                                 }
890
891                                 newCellJsonStr, err := json.Marshal(&cellMetrics)
892                                 if err != nil {
893                                         xapp.Logger.Error("Failed to marshal CellMetrics with CellID [%s]: %v", cellIDHdr, err)
894                                         log.Printf("Failed to marshal CellMetrics with CellID [%s]: %v", cellIDHdr, err)
895                                         continue
896                                 }
897                                 err = c.client.Set("{TS-cell-metrics}," + cellIDHdr, newCellJsonStr, 0).Err()
898                                 if err != nil {
899                                         xapp.Logger.Error("Failed to set CellMetrics into redis with CellID [%s]: %v", cellIDHdr, err)
900                                         log.Printf("Failed to set CellMetrics into redis with CellID [%s]: %v", cellIDHdr, err)
901                                         continue
902                                 }
903                         }
904                 }
905         } else {
906                 xapp.Logger.Error("Unknown RIC Indication Message Format: %d", indMsg.IndMsgType)
907                 log.Printf("Unkonw RIC Indication Message Format: %d", indMsg.IndMsgType)
908                 return
909         }
910
911         return nil
912 }
913
914 func (c *Control) handleSubscriptionResponse(params *xapp.RMRParams) (err error) {
915         xapp.Logger.Debug("The SubId in RIC_SUB_RESP is %d", params.SubId)
916         log.Printf("The SubId in RIC_SUB_RESP is %d", params.SubId)
917
918         ranName := params.Meid.RanName
919         c.eventCreateExpiredMu.Lock()
920         _, ok := c.eventCreateExpiredMap[ranName]
921         if !ok {
922                 c.eventCreateExpiredMu.Unlock()
923                 xapp.Logger.Debug("RIC_SUB_REQ has been deleted!")
924                 log.Printf("RIC_SUB_REQ has been deleted!")
925                 return nil
926         } else {
927                 c.eventCreateExpiredMap[ranName] = true
928                 c.eventCreateExpiredMu.Unlock()
929         }
930
931         var cep *E2ap
932         subscriptionResp, err := cep.GetSubscriptionResponseMessage(params.Payload)
933         if err != nil {
934                 xapp.Logger.Error("Failed to decode RIC Subscription Response message: %v", err)
935                 log.Printf("Failed to decode RIC Subscription Response message: %v", err)
936                 return
937         }
938
939         log.Printf("RIC Subscription Response message from {%s} received", params.Meid.RanName)
940         log.Printf("SubscriptionID: %d", params.SubId)
941         log.Printf("RequestID: %d", subscriptionResp.RequestID)
942         log.Printf("RequestSequenceNumber: %d", subscriptionResp.RequestSequenceNumber)
943         log.Printf("FunctionID: %d", subscriptionResp.FuncID)
944
945         log.Printf("ActionAdmittedList:")
946         for index := 0; index < subscriptionResp.ActionAdmittedList.Count; index++ {
947                 log.Printf("[%d]ActionID: %d", index, subscriptionResp.ActionAdmittedList.ActionID[index])
948         }
949
950         log.Printf("ActionNotAdmittedList:")
951         for index := 0; index < subscriptionResp.ActionNotAdmittedList.Count; index++ {
952                 log.Printf("[%d]ActionID: %d", index, subscriptionResp.ActionNotAdmittedList.ActionID[index])
953                 log.Printf("[%d]CauseType: %d    CauseID: %d", index, subscriptionResp.ActionNotAdmittedList.Cause[index].CauseType, subscriptionResp.ActionNotAdmittedList.Cause[index].CauseID)
954         }
955
956         return nil
957 }
958
959 func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) (err error) {
960         xapp.Logger.Debug("The SubId in RIC_SUB_FAILURE is %d", params.SubId)
961         log.Printf("The SubId in RIC_SUB_FAILURE is %d", params.SubId)
962
963         ranName := params.Meid.RanName
964         c.eventCreateExpiredMu.Lock()
965         _, ok := c.eventCreateExpiredMap[ranName]
966         if !ok {
967                 c.eventCreateExpiredMu.Unlock()
968                 xapp.Logger.Debug("RIC_SUB_REQ has been deleted!")
969                 log.Printf("RIC_SUB_REQ has been deleted!")
970                 return nil
971         } else {
972                 c.eventCreateExpiredMap[ranName] = true
973                 c.eventCreateExpiredMu.Unlock()
974         }
975
976         return nil
977 }
978
979 func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
980         xapp.Logger.Debug("The SubId in RIC_SUB_DEL_RESP is %d", params.SubId)
981         log.Printf("The SubId in RIC_SUB_DEL_RESP is %d", params.SubId)
982
983         ranName := params.Meid.RanName
984         c.eventDeleteExpiredMu.Lock()
985         _, ok := c.eventDeleteExpiredMap[ranName]
986         if !ok {
987                 c.eventDeleteExpiredMu.Unlock()
988                 xapp.Logger.Debug("RIC_SUB_DEL_REQ has been deleted!")
989                 log.Printf("RIC_SUB_DEL_REQ has been deleted!")
990                 return nil
991         } else {
992                 c.eventDeleteExpiredMap[ranName] = true
993                 c.eventDeleteExpiredMu.Unlock()
994         }
995
996         return nil
997 }
998
999 func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) (err error) {
1000         xapp.Logger.Debug("The SubId in RIC_SUB_DEL_FAILURE is %d", params.SubId)
1001         log.Printf("The SubId in RIC_SUB_DEL_FAILURE is %d", params.SubId)
1002
1003         ranName := params.Meid.RanName
1004         c.eventDeleteExpiredMu.Lock()
1005         _, ok := c.eventDeleteExpiredMap[ranName]
1006         if !ok {
1007                 c.eventDeleteExpiredMu.Unlock()
1008                 xapp.Logger.Debug("RIC_SUB_DEL_REQ has been deleted!")
1009                 log.Printf("RIC_SUB_DEL_REQ has been deleted!")
1010                 return nil
1011         } else {
1012                 c.eventDeleteExpiredMap[ranName] = true
1013                 c.eventDeleteExpiredMu.Unlock()
1014         }
1015
1016         return nil
1017 }
1018
1019 func (c *Control) setEventCreateExpiredTimer(ranName string) {
1020         c.eventCreateExpiredMu.Lock()
1021         c.eventCreateExpiredMap[ranName] = false
1022         c.eventCreateExpiredMu.Unlock()
1023
1024         timer := time.NewTimer(time.Duration(c.eventCreateExpired) * time.Second)
1025         go func(t *time.Timer) {
1026                 defer t.Stop()
1027                 xapp.Logger.Debug("RIC_SUB_REQ[%s]: Waiting for RIC_SUB_RESP...", ranName)
1028                 log.Printf("RIC_SUB_REQ[%s]: Waiting for RIC_SUB_RESP...", ranName)
1029                 for {
1030                         select {
1031                         case <-t.C:
1032                                 c.eventCreateExpiredMu.Lock()
1033                                 isResponsed := c.eventCreateExpiredMap[ranName]
1034                                 delete(c.eventCreateExpiredMap, ranName)
1035                                 c.eventCreateExpiredMu.Unlock()
1036                                 if !isResponsed {
1037                                         xapp.Logger.Debug("RIC_SUB_REQ[%s]: RIC Event Create Timer experied!", ranName)
1038                                         log.Printf("RIC_SUB_REQ[%s]: RIC Event Create Timer experied!", ranName)
1039                                         // c.sendRicSubDelRequest(subID, requestSN, funcID)
1040                                         return
1041                                 }
1042                         default:
1043                                 c.eventCreateExpiredMu.Lock()
1044                                 flag := c.eventCreateExpiredMap[ranName]
1045                                 if flag {
1046                                         delete(c.eventCreateExpiredMap, ranName)
1047                                         c.eventCreateExpiredMu.Unlock()
1048                                         xapp.Logger.Debug("RIC_SUB_REQ[%s]: RIC Event Create Timer canceled!", ranName)
1049                                         log.Printf("RIC_SUB_REQ[%s]: RIC Event Create Timer canceled!", ranName)
1050                                         return
1051                                 } else {
1052                                         c.eventCreateExpiredMu.Unlock()
1053                                 }
1054                         }
1055                         time.Sleep(100 * time.Millisecond)
1056                 }
1057         }(timer)
1058 }
1059
1060 func (c *Control) setEventDeleteExpiredTimer(ranName string) {
1061         c.eventDeleteExpiredMu.Lock()
1062         c.eventDeleteExpiredMap[ranName] = false
1063         c.eventDeleteExpiredMu.Unlock()
1064
1065         timer := time.NewTimer(time.Duration(c.eventDeleteExpired) * time.Second)
1066         go func(t *time.Timer) {
1067                 defer t.Stop()
1068                 xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: Waiting for RIC_SUB_DEL_RESP...", ranName)
1069                 log.Printf("RIC_SUB_DEL_REQ[%s]: Waiting for RIC_SUB_DEL_RESP...", ranName)
1070                 for {
1071                         select {
1072                         case <-t.C:
1073                                 c.eventDeleteExpiredMu.Lock()
1074                                 isResponsed := c.eventDeleteExpiredMap[ranName]
1075                                 delete(c.eventDeleteExpiredMap, ranName)
1076                                 c.eventDeleteExpiredMu.Unlock()
1077                                 if !isResponsed {
1078                                         xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer experied!", ranName)
1079                                         log.Printf("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer experied!", ranName)
1080                                         return
1081                                 }
1082                         default:
1083                                 c.eventDeleteExpiredMu.Lock()
1084                                 flag := c.eventDeleteExpiredMap[ranName]
1085                                 if flag {
1086                                         delete(c.eventDeleteExpiredMap, ranName)
1087                                         c.eventDeleteExpiredMu.Unlock()
1088                                         xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer canceled!", ranName)
1089                                         log.Printf("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer canceled!", ranName)
1090                                         return
1091                                 } else {
1092                                         c.eventDeleteExpiredMu.Unlock()
1093                                 }
1094                         }
1095                         time.Sleep(100 * time.Millisecond)
1096                 }
1097         }(timer)
1098 }
1099
1100 func (c *Control) sendRicSubRequest(subID int, requestSN int, funcID int) (err error) {
1101         var e2ap *E2ap
1102         var e2sm *E2sm
1103
1104         var eventTriggerCount int = 1
1105         var periods []int64 = []int64{13}
1106         var eventTriggerDefinition []byte = make([]byte, 8)
1107         _, err = e2sm.SetEventTriggerDefinition(eventTriggerDefinition, eventTriggerCount, periods)
1108         if err != nil {
1109                 xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1110                 log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1111                 return err
1112         }
1113         log.Printf("Set EventTriggerDefinition: %x", eventTriggerDefinition)
1114
1115         var actionCount int = 1
1116         var ricStyleType []int64 = []int64{0}
1117         var actionIds []int64 = []int64{0}
1118         var actionTypes []int64 = []int64{0}
1119         var actionDefinitions []ActionDefinition = make([]ActionDefinition, actionCount)
1120         var subsequentActions []SubsequentAction = []SubsequentAction{SubsequentAction{0, 0, 0}}
1121
1122         for index := 0; index < actionCount; index++ {
1123                 if ricStyleType[index] == 0 {
1124                         actionDefinitions[index].Buf = nil
1125                         actionDefinitions[index].Size = 0
1126                 } else {
1127                         actionDefinitions[index].Buf = make([]byte, 8)
1128                         _, err = e2sm.SetActionDefinition(actionDefinitions[index].Buf, ricStyleType[index])
1129                         if err != nil {
1130                                 xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1131                                 log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1132                                 return err
1133                         }
1134                         actionDefinitions[index].Size = len(actionDefinitions[index].Buf)
1135
1136                         log.Printf("Set ActionDefinition[%d]: %x", index, actionDefinitions[index].Buf)
1137                 }
1138         }
1139
1140         for index := 0; index < 1; index++ { //len(c.ranList)
1141                 params := &xapp.RMRParams{}
1142                 params.Mtype = 12010
1143                 params.SubId = subID
1144
1145                 //xapp.Logger.Debug("Send RIC_SUB_REQ to {%s}", c.ranList[index])
1146                 //log.Printf("Send RIC_SUB_REQ to {%s}", c.ranList[index])
1147
1148                 params.Payload = make([]byte, 1024)
1149                 params.Payload, err = e2ap.SetSubscriptionRequestPayload(params.Payload, 1001, uint16(requestSN), uint16(funcID), eventTriggerDefinition, len(eventTriggerDefinition), actionCount, actionIds, actionTypes, actionDefinitions, subsequentActions)
1150                 if err != nil {
1151                         xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1152                         log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1153                         return err
1154                 }
1155
1156                 log.Printf("Set Payload: %x", params.Payload)
1157
1158                 //params.Meid = &xapp.RMRMeid{RanName: c.ranList[index]}
1159                 params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"}
1160                 xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1161                 log.Printf("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1162
1163                 err = c.rmrSend(params)
1164                 if err != nil {
1165                         xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1166                         log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1167                         return err
1168                 }
1169
1170                 c.setEventCreateExpiredTimer(params.Meid.RanName)
1171                 //c.ranList = append(c.ranList[:index], c.ranList[index+1:]...)
1172                 //index--
1173         }
1174
1175         return nil
1176 }
1177
1178 func (c *Control) sendRicSubDelRequest(subID int, requestSN int, funcID int) (err error) {
1179         params := &xapp.RMRParams{}
1180         params.Mtype = 12020
1181         params.SubId = subID
1182         var e2ap *E2ap
1183
1184         params.Payload = make([]byte, 1024)
1185         params.Payload, err = e2ap.SetSubscriptionDeleteRequestPayload(params.Payload, 100, uint16(requestSN), uint16(funcID))
1186         if err != nil {
1187                 xapp.Logger.Error("Failed to send RIC_SUB_DEL_REQ: %v", err)
1188                 return err
1189         }
1190
1191         log.Printf("Set Payload: %x", params.Payload)
1192
1193         if funcID == 0 {
1194                 //params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "0"}
1195                 params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"}
1196         } else {
1197                 //params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "3"}
1198                 params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"}
1199         }
1200
1201         xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1202         log.Printf("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1203
1204         err = c.rmrSend(params)
1205         if err != nil {
1206                 xapp.Logger.Error("Failed to send RIC_SUB_DEL_REQ: %v", err)
1207                 log.Printf("Failed to send RIC_SUB_DEL_REQ: %v", err)
1208                 return err
1209         }
1210
1211         c.setEventDeleteExpiredTimer(params.Meid.RanName)
1212
1213         return nil
1214 }