Set "UE ID" field in Ue Metrics.
[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(strconv.FormatInt(ueID, 10)).Result(); isUeExist == 1 {
648                                                                 ueJsonStr, _ := c.client.Get(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
657                                                         if flag {
658                                                                 timestampPRB = timestamp
659                                                         }
660
661                                                         ueMetrics.MeasTimestampPRB.TVsec = timestamp.TVsec
662                                                         ueMetrics.MeasTimestampPRB.TVnsec = timestamp.TVnsec
663
664                                                         if ueResourceReportItem.PRBUsageDL != -1 {
665                                                                 ueMetrics.PRBUsageDL = ueResourceReportItem.PRBUsageDL
666                                                                 log.Printf("PRBUsageDL: %d", ueMetrics.PRBUsageDL)
667                                                         }
668
669                                                         if ueResourceReportItem.PRBUsageUL != -1 {
670                                                                 ueMetrics.PRBUsageUL = ueResourceReportItem.PRBUsageUL
671                                                                 log.Printf("PRBUsageUL: %d", ueMetrics.PRBUsageUL)
672                                                         }
673
674                                                         newUeJsonStr, err := json.Marshal(&ueMetrics)
675                                                         if err != nil {
676                                                                 xapp.Logger.Error("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
677                                                                 log.Printf("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
678                                                                 continue
679                                                         }
680                                                         err = c.client.Set(strconv.FormatInt(ueID, 10), newUeJsonStr, 0).Err()
681                                                         if err != nil {
682                                                                 xapp.Logger.Error("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
683                                                                 log.Printf("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
684                                                                 continue
685                                                         }
686                                                 }
687                                         }
688                                 } else if containerType == 2 {
689                                         log.Printf("CU-CP Usage Report: ")
690
691                                         oCUCPUE := pmContainer.RANContainer.Container.(*CUCPUsageReportType)
692
693                                         for j := 0; j < oCUCPUE.CellResourceReportItemCount; j++ {
694                                                 cellResourceReportItem := oCUCPUE.CellResourceReportItems[j]
695
696                                                 log.Printf("nRCGI.PlmnID: %x", cellResourceReportItem.NRCGI.PlmnID.Buf)
697                                                 log.Printf("nRCGI.NRCellID: %x, Unused: %d", cellResourceReportItem.NRCGI.NRCellID.Buf, cellResourceReportItem.NRCGI.NRCellID.BitsUnused)
698
699                                                 servingCellID, err := e2sm.ParseNRCGI(cellResourceReportItem.NRCGI)
700                                                 if err != nil {
701                                                         xapp.Logger.Error("Failed to parse NRCGI in CU-CP Usage Report: %v", err)
702                                                         log.Printf("Failed to parse NRCGI in CU-CP Usage Report: %v", err)
703                                                         continue
704                                                 }
705
706                                                 for k := 0; k < cellResourceReportItem.UeResourceReportItemCount; k++ {
707                                                         ueResourceReportItem := cellResourceReportItem.UeResourceReportItems[k]
708
709                                                         log.Printf("C-RNTI: %x", ueResourceReportItem.CRNTI.Buf)
710
711                                                         ueID, err := e2sm.ParseInteger(ueResourceReportItem.CRNTI.Buf, ueResourceReportItem.CRNTI.Size)
712                                                         if err != nil {
713                                                                 xapp.Logger.Error("Failed to parse C-RNTI in CU-CP Usage Report with Serving Cell ID [%s]: %v", err)
714                                                                 log.Printf("Failed to parse C-RNTI in CU-CP Usage Report with Serving Cell ID [%s]: %v", err)
715                                                                 continue
716                                                         }
717
718                                                         var ueMetrics UeMetricsEntry
719                                                         if isUeExist, _ := c.client.Exists(strconv.FormatInt(ueID, 10)).Result(); isUeExist == 1 {
720                                                                 ueJsonStr, _ := c.client.Get(strconv.FormatInt(ueID, 10)).Result()
721                                                                 json.Unmarshal([]byte(ueJsonStr), &ueMetrics)
722                                                         }
723
724                                                         ueMetrics.UeID = ueID
725                                                         log.Printf("UeID: %d", ueMetrics.UeID)
726                                                         ueMetrics.ServingCellID = servingCellID
727                                                         log.Printf("ServingCellID: %s", ueMetrics.ServingCellID)
728
729                                                         ueMetrics.MeasTimeRF.TVsec = timestamp.TVsec
730                                                         ueMetrics.MeasTimeRF.TVnsec = timestamp.TVnsec
731
732                                                         if ueResourceReportItem.ServingCellRF != nil {
733                                                                 err = json.Unmarshal(ueResourceReportItem.ServingCellRF.Buf, &ueMetrics.ServingCellRF)
734                                                                 log.Printf("ueMetrics.ServingCellRF: %+v", ueMetrics.ServingCellRF)
735                                                                 if err != nil {
736                                                                         xapp.Logger.Error("Failed to Unmarshal ServingCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
737                                                                         log.Printf("Failed to Unmarshal ServingCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
738                                                                         log.Printf("ServingCellRF raw data: %x", ueResourceReportItem.ServingCellRF.Buf)
739                                                                         continue
740                                                                 }
741                                                         }
742
743                                                         if ueResourceReportItem.NeighborCellRF != nil {
744                                                                 err = json.Unmarshal(ueResourceReportItem.NeighborCellRF.Buf, &ueMetrics.NeighborCellsRF)
745                                                                 log.Printf("ueMetrics.NeighborCellsRF: %+v", ueMetrics.NeighborCellsRF)
746                                                                 if err != nil {
747                                                                         xapp.Logger.Error("Failed to Unmarshal NeighborCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
748                                                                         log.Printf("Failed to Unmarshal NeighborCellRF in CU-CP Usage Report with UE ID [%d]: %v", ueID, err)
749                                                                         log.Printf("NeighborCellRF raw data: %x", ueResourceReportItem.NeighborCellRF.Buf)
750                                                                         continue
751                                                                 }
752                                                         }
753
754                                                         newUeJsonStr, err := json.Marshal(&ueMetrics)
755                                                         if err != nil {
756                                                                 xapp.Logger.Error("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
757                                                                 log.Printf("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
758                                                                 continue
759                                                         }
760                                                         err = c.client.Set(strconv.FormatInt(ueID, 10), newUeJsonStr, 0).Err()
761                                                         if err != nil {
762                                                                 xapp.Logger.Error("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
763                                                                 log.Printf("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
764                                                                 continue
765                                                         }
766                                                 }
767                                         }
768                                 } else if containerType == 3 {
769                                         log.Printf("CU-UP Usage Report: ")
770
771                                         oCUUPUE := pmContainer.RANContainer.Container.(*CUUPUsageReportType)
772
773                                         for j := 0; j < oCUUPUE.CellResourceReportItemCount; j++ {
774                                                 cellResourceReportItem := oCUUPUE.CellResourceReportItems[j]
775
776                                                 log.Printf("nRCGI.PlmnID: %x", cellResourceReportItem.NRCGI.PlmnID.Buf)
777                                                 log.Printf("nRCGI.NRCellID: %x, Unused: %d", cellResourceReportItem.NRCGI.NRCellID.Buf, cellResourceReportItem.NRCGI.NRCellID.BitsUnused)
778
779                                                 servingCellID, err := e2sm.ParseNRCGI(cellResourceReportItem.NRCGI)
780                                                 if err != nil {
781                                                         xapp.Logger.Error("Failed to parse NRCGI in CU-UP Usage Report: %v", err)
782                                                         log.Printf("Failed to parse NRCGI in CU-UP Usage Report: %v", err)
783                                                         continue
784                                                 }
785
786                                                 for k := 0; k < cellResourceReportItem.UeResourceReportItemCount; k++ {
787                                                         ueResourceReportItem := cellResourceReportItem.UeResourceReportItems[k]
788
789                                                         log.Printf("C-RNTI: %x", ueResourceReportItem.CRNTI.Buf)
790
791                                                         ueID, err := e2sm.ParseInteger(ueResourceReportItem.CRNTI.Buf, ueResourceReportItem.CRNTI.Size)
792                                                         if err != nil {
793                                                                 xapp.Logger.Error("Failed to parse C-RNTI in CU-UP Usage Report Serving Cell ID [%s]: %v", servingCellID, err)
794                                                                 log.Printf("Failed to parse C-RNTI in CU-UP Usage Report Serving Cell ID [%s]: %v", servingCellID, err)
795                                                                 continue
796                                                         }
797
798                                                         var ueMetrics UeMetricsEntry
799                                                         if isUeExist, _ := c.client.Exists(strconv.FormatInt(ueID, 10)).Result(); isUeExist == 1 {
800                                                                 ueJsonStr, _ := c.client.Get(strconv.FormatInt(ueID, 10)).Result()
801                                                                 json.Unmarshal([]byte(ueJsonStr), &ueMetrics)
802                                                         }
803
804                                                         ueMetrics.UeID = ueID
805                                                         log.Printf("UeID: %d", ueMetrics.UeID)
806                                                         ueMetrics.ServingCellID = servingCellID
807                                                         log.Printf("ServingCellID: %s", ueMetrics.ServingCellID)
808
809                                                         if flag {
810                                                                 timestampPDCPBytes = timestamp
811                                                         }
812
813                                                         ueMetrics.MeasTimestampPDCPBytes.TVsec = timestamp.TVsec
814                                                         ueMetrics.MeasTimestampPDCPBytes.TVnsec = timestamp.TVnsec
815
816                                                         if ueResourceReportItem.PDCPBytesDL != nil {
817                                                                 ueMetrics.PDCPBytesDL, err = e2sm.ParseInteger(ueResourceReportItem.PDCPBytesDL.Buf, ueResourceReportItem.PDCPBytesDL.Size)
818                                                                 if err != nil {
819                                                                         xapp.Logger.Error("Failed to parse PDCPBytesDL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
820                                                                         log.Printf("Failed to parse PDCPBytesDL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
821                                                                         continue
822                                                                 }
823                                                         }
824
825                                                         if ueResourceReportItem.PDCPBytesUL != nil {
826                                                                 ueMetrics.PDCPBytesUL, err = e2sm.ParseInteger(ueResourceReportItem.PDCPBytesUL.Buf, ueResourceReportItem.PDCPBytesUL.Size)
827                                                                 if err != nil {
828                                                                         xapp.Logger.Error("Failed to parse PDCPBytesUL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
829                                                                         log.Printf("Failed to parse PDCPBytesUL in CU-UP Usage Report with UE ID [%d]: %v", ueID, err)
830                                                                         continue
831                                                                 }
832                                                         }
833
834                                                         newUeJsonStr, err := json.Marshal(&ueMetrics)
835                                                         if err != nil {
836                                                                 xapp.Logger.Error("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
837                                                                 log.Printf("Failed to marshal UeMetrics with UE ID [%d]: %v", ueID, err)
838                                                                 continue
839                                                         }
840                                                         err = c.client.Set(strconv.FormatInt(ueID, 10), newUeJsonStr, 0).Err()
841                                                         if err != nil {
842                                                                 xapp.Logger.Error("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
843                                                                 log.Printf("Failed to set UeMetrics into redis with UE ID [%d]: %v", ueID, err)
844                                                                 continue
845                                                         }
846                                                 }
847                                         }
848                                 } else {
849                                         xapp.Logger.Error("Unknown PF Container Type: %d", containerType)
850                                         log.Printf("Unknown PF Container Type: %d", containerType)
851                                         continue
852                                 }
853                         }
854
855                         if flag {
856                                 var cellMetrics CellMetricsEntry
857                                 if isCellExist, _ := c.client.Exists(cellIDHdr).Result(); isCellExist == 1 {
858                                         cellJsonStr, _ := c.client.Get(cellIDHdr).Result()
859                                         json.Unmarshal([]byte(cellJsonStr), &cellMetrics)
860                                 }
861
862                                 if timestampPDCPBytes != nil {
863                                         cellMetrics.MeasTimestampPDCPBytes.TVsec = timestampPDCPBytes.TVsec
864                                         cellMetrics.MeasTimestampPDCPBytes.TVnsec = timestampPDCPBytes.TVnsec
865                                 }
866                                 if dlPDCPBytes != -1 {
867                                         cellMetrics.PDCPBytesDL = dlPDCPBytes
868                                 }
869                                 if ulPDCPBytes != -1 {
870                                         cellMetrics.PDCPBytesUL = ulPDCPBytes
871                                 }
872                                 if timestampPRB != nil {
873                                         cellMetrics.MeasTimestampPRB.TVsec = timestampPRB.TVsec
874                                         cellMetrics.MeasTimestampPRB.TVnsec = timestampPRB.TVnsec
875                                 }
876                                 if availPRBDL != -1 {
877                                         cellMetrics.AvailPRBDL = availPRBDL
878                                 }
879                                 if availPRBUL != -1 {
880                                         cellMetrics.AvailPRBUL = availPRBUL
881                                 }
882
883                                 newCellJsonStr, err := json.Marshal(&cellMetrics)
884                                 if err != nil {
885                                         xapp.Logger.Error("Failed to marshal CellMetrics with CellID [%s]: %v", cellIDHdr, err)
886                                         log.Printf("Failed to marshal CellMetrics with CellID [%s]: %v", cellIDHdr, err)
887                                         continue
888                                 }
889                                 err = c.client.Set(cellIDHdr, newCellJsonStr, 0).Err()
890                                 if err != nil {
891                                         xapp.Logger.Error("Failed to set CellMetrics into redis with CellID [%s]: %v", cellIDHdr, err)
892                                         log.Printf("Failed to set CellMetrics into redis with CellID [%s]: %v", cellIDHdr, err)
893                                         continue
894                                 }
895                         }
896                 }
897         } else {
898                 xapp.Logger.Error("Unknown RIC Indication Message Format: %d", indMsg.IndMsgType)
899                 log.Printf("Unkonw RIC Indication Message Format: %d", indMsg.IndMsgType)
900                 return
901         }
902
903         return nil
904 }
905
906 func (c *Control) handleSubscriptionResponse(params *xapp.RMRParams) (err error) {
907         xapp.Logger.Debug("The SubId in RIC_SUB_RESP is %d", params.SubId)
908         log.Printf("The SubId in RIC_SUB_RESP is %d", params.SubId)
909
910         ranName := params.Meid.RanName
911         c.eventCreateExpiredMu.Lock()
912         _, ok := c.eventCreateExpiredMap[ranName]
913         if !ok {
914                 c.eventCreateExpiredMu.Unlock()
915                 xapp.Logger.Debug("RIC_SUB_REQ has been deleted!")
916                 log.Printf("RIC_SUB_REQ has been deleted!")
917                 return nil
918         } else {
919                 c.eventCreateExpiredMap[ranName] = true
920                 c.eventCreateExpiredMu.Unlock()
921         }
922
923         var cep *E2ap
924         subscriptionResp, err := cep.GetSubscriptionResponseMessage(params.Payload)
925         if err != nil {
926                 xapp.Logger.Error("Failed to decode RIC Subscription Response message: %v", err)
927                 log.Printf("Failed to decode RIC Subscription Response message: %v", err)
928                 return
929         }
930
931         log.Printf("RIC Subscription Response message from {%s} received", params.Meid.RanName)
932         log.Printf("SubscriptionID: %d", params.SubId)
933         log.Printf("RequestID: %d", subscriptionResp.RequestID)
934         log.Printf("RequestSequenceNumber: %d", subscriptionResp.RequestSequenceNumber)
935         log.Printf("FunctionID: %d", subscriptionResp.FuncID)
936
937         log.Printf("ActionAdmittedList:")
938         for index := 0; index < subscriptionResp.ActionAdmittedList.Count; index++ {
939                 log.Printf("[%d]ActionID: %d", index, subscriptionResp.ActionAdmittedList.ActionID[index])
940         }
941
942         log.Printf("ActionNotAdmittedList:")
943         for index := 0; index < subscriptionResp.ActionNotAdmittedList.Count; index++ {
944                 log.Printf("[%d]ActionID: %d", index, subscriptionResp.ActionNotAdmittedList.ActionID[index])
945                 log.Printf("[%d]CauseType: %d    CauseID: %d", index, subscriptionResp.ActionNotAdmittedList.Cause[index].CauseType, subscriptionResp.ActionNotAdmittedList.Cause[index].CauseID)
946         }
947
948         return nil
949 }
950
951 func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) (err error) {
952         xapp.Logger.Debug("The SubId in RIC_SUB_FAILURE is %d", params.SubId)
953         log.Printf("The SubId in RIC_SUB_FAILURE is %d", params.SubId)
954
955         ranName := params.Meid.RanName
956         c.eventCreateExpiredMu.Lock()
957         _, ok := c.eventCreateExpiredMap[ranName]
958         if !ok {
959                 c.eventCreateExpiredMu.Unlock()
960                 xapp.Logger.Debug("RIC_SUB_REQ has been deleted!")
961                 log.Printf("RIC_SUB_REQ has been deleted!")
962                 return nil
963         } else {
964                 c.eventCreateExpiredMap[ranName] = true
965                 c.eventCreateExpiredMu.Unlock()
966         }
967
968         return nil
969 }
970
971 func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
972         xapp.Logger.Debug("The SubId in RIC_SUB_DEL_RESP is %d", params.SubId)
973         log.Printf("The SubId in RIC_SUB_DEL_RESP is %d", params.SubId)
974
975         ranName := params.Meid.RanName
976         c.eventDeleteExpiredMu.Lock()
977         _, ok := c.eventDeleteExpiredMap[ranName]
978         if !ok {
979                 c.eventDeleteExpiredMu.Unlock()
980                 xapp.Logger.Debug("RIC_SUB_DEL_REQ has been deleted!")
981                 log.Printf("RIC_SUB_DEL_REQ has been deleted!")
982                 return nil
983         } else {
984                 c.eventDeleteExpiredMap[ranName] = true
985                 c.eventDeleteExpiredMu.Unlock()
986         }
987
988         return nil
989 }
990
991 func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) (err error) {
992         xapp.Logger.Debug("The SubId in RIC_SUB_DEL_FAILURE is %d", params.SubId)
993         log.Printf("The SubId in RIC_SUB_DEL_FAILURE is %d", params.SubId)
994
995         ranName := params.Meid.RanName
996         c.eventDeleteExpiredMu.Lock()
997         _, ok := c.eventDeleteExpiredMap[ranName]
998         if !ok {
999                 c.eventDeleteExpiredMu.Unlock()
1000                 xapp.Logger.Debug("RIC_SUB_DEL_REQ has been deleted!")
1001                 log.Printf("RIC_SUB_DEL_REQ has been deleted!")
1002                 return nil
1003         } else {
1004                 c.eventDeleteExpiredMap[ranName] = true
1005                 c.eventDeleteExpiredMu.Unlock()
1006         }
1007
1008         return nil
1009 }
1010
1011 func (c *Control) setEventCreateExpiredTimer(ranName string) {
1012         c.eventCreateExpiredMu.Lock()
1013         c.eventCreateExpiredMap[ranName] = false
1014         c.eventCreateExpiredMu.Unlock()
1015
1016         timer := time.NewTimer(time.Duration(c.eventCreateExpired) * time.Second)
1017         go func(t *time.Timer) {
1018                 defer t.Stop()
1019                 xapp.Logger.Debug("RIC_SUB_REQ[%s]: Waiting for RIC_SUB_RESP...", ranName)
1020                 log.Printf("RIC_SUB_REQ[%s]: Waiting for RIC_SUB_RESP...", ranName)
1021                 for {
1022                         select {
1023                         case <-t.C:
1024                                 c.eventCreateExpiredMu.Lock()
1025                                 isResponsed := c.eventCreateExpiredMap[ranName]
1026                                 delete(c.eventCreateExpiredMap, ranName)
1027                                 c.eventCreateExpiredMu.Unlock()
1028                                 if !isResponsed {
1029                                         xapp.Logger.Debug("RIC_SUB_REQ[%s]: RIC Event Create Timer experied!", ranName)
1030                                         log.Printf("RIC_SUB_REQ[%s]: RIC Event Create Timer experied!", ranName)
1031                                         // c.sendRicSubDelRequest(subID, requestSN, funcID)
1032                                         return
1033                                 }
1034                         default:
1035                                 c.eventCreateExpiredMu.Lock()
1036                                 flag := c.eventCreateExpiredMap[ranName]
1037                                 if flag {
1038                                         delete(c.eventCreateExpiredMap, ranName)
1039                                         c.eventCreateExpiredMu.Unlock()
1040                                         xapp.Logger.Debug("RIC_SUB_REQ[%s]: RIC Event Create Timer canceled!", ranName)
1041                                         log.Printf("RIC_SUB_REQ[%s]: RIC Event Create Timer canceled!", ranName)
1042                                         return
1043                                 } else {
1044                                         c.eventCreateExpiredMu.Unlock()
1045                                 }
1046                         }
1047                         time.Sleep(100 * time.Millisecond)
1048                 }
1049         }(timer)
1050 }
1051
1052 func (c *Control) setEventDeleteExpiredTimer(ranName string) {
1053         c.eventDeleteExpiredMu.Lock()
1054         c.eventDeleteExpiredMap[ranName] = false
1055         c.eventDeleteExpiredMu.Unlock()
1056
1057         timer := time.NewTimer(time.Duration(c.eventDeleteExpired) * time.Second)
1058         go func(t *time.Timer) {
1059                 defer t.Stop()
1060                 xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: Waiting for RIC_SUB_DEL_RESP...", ranName)
1061                 log.Printf("RIC_SUB_DEL_REQ[%s]: Waiting for RIC_SUB_DEL_RESP...", ranName)
1062                 for {
1063                         select {
1064                         case <-t.C:
1065                                 c.eventDeleteExpiredMu.Lock()
1066                                 isResponsed := c.eventDeleteExpiredMap[ranName]
1067                                 delete(c.eventDeleteExpiredMap, ranName)
1068                                 c.eventDeleteExpiredMu.Unlock()
1069                                 if !isResponsed {
1070                                         xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer experied!", ranName)
1071                                         log.Printf("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer experied!", ranName)
1072                                         return
1073                                 }
1074                         default:
1075                                 c.eventDeleteExpiredMu.Lock()
1076                                 flag := c.eventDeleteExpiredMap[ranName]
1077                                 if flag {
1078                                         delete(c.eventDeleteExpiredMap, ranName)
1079                                         c.eventDeleteExpiredMu.Unlock()
1080                                         xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer canceled!", ranName)
1081                                         log.Printf("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer canceled!", ranName)
1082                                         return
1083                                 } else {
1084                                         c.eventDeleteExpiredMu.Unlock()
1085                                 }
1086                         }
1087                         time.Sleep(100 * time.Millisecond)
1088                 }
1089         }(timer)
1090 }
1091
1092 func (c *Control) sendRicSubRequest(subID int, requestSN int, funcID int) (err error) {
1093         var e2ap *E2ap
1094         var e2sm *E2sm
1095
1096         var eventTriggerCount int = 1
1097         var periods []int64 = []int64{13}
1098         var eventTriggerDefinition []byte = make([]byte, 8)
1099         _, err = e2sm.SetEventTriggerDefinition(eventTriggerDefinition, eventTriggerCount, periods)
1100         if err != nil {
1101                 xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1102                 log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1103                 return err
1104         }
1105         log.Printf("Set EventTriggerDefinition: %x", eventTriggerDefinition)
1106
1107         var actionCount int = 1
1108         var ricStyleType []int64 = []int64{0}
1109         var actionIds []int64 = []int64{0}
1110         var actionTypes []int64 = []int64{0}
1111         var actionDefinitions []ActionDefinition = make([]ActionDefinition, actionCount)
1112         var subsequentActions []SubsequentAction = []SubsequentAction{SubsequentAction{0, 0, 0}}
1113
1114         for index := 0; index < actionCount; index++ {
1115                 if ricStyleType[index] == 0 {
1116                         actionDefinitions[index].Buf = nil
1117                         actionDefinitions[index].Size = 0
1118                 } else {
1119                         actionDefinitions[index].Buf = make([]byte, 8)
1120                         _, err = e2sm.SetActionDefinition(actionDefinitions[index].Buf, ricStyleType[index])
1121                         if err != nil {
1122                                 xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1123                                 log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1124                                 return err
1125                         }
1126                         actionDefinitions[index].Size = len(actionDefinitions[index].Buf)
1127
1128                         log.Printf("Set ActionDefinition[%d]: %x", index, actionDefinitions[index].Buf)
1129                 }
1130         }
1131
1132         for index := 0; index < 1; index++ { //len(c.ranList)
1133                 params := &xapp.RMRParams{}
1134                 params.Mtype = 12010
1135                 params.SubId = subID
1136
1137                 //xapp.Logger.Debug("Send RIC_SUB_REQ to {%s}", c.ranList[index])
1138                 //log.Printf("Send RIC_SUB_REQ to {%s}", c.ranList[index])
1139
1140                 params.Payload = make([]byte, 1024)
1141                 params.Payload, err = e2ap.SetSubscriptionRequestPayload(params.Payload, 1001, uint16(requestSN), uint16(funcID), eventTriggerDefinition, len(eventTriggerDefinition), actionCount, actionIds, actionTypes, actionDefinitions, subsequentActions)
1142                 if err != nil {
1143                         xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1144                         log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1145                         return err
1146                 }
1147
1148                 log.Printf("Set Payload: %x", params.Payload)
1149
1150                 //params.Meid = &xapp.RMRMeid{RanName: c.ranList[index]}
1151                 params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"}
1152                 xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1153                 log.Printf("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1154
1155                 err = c.rmrSend(params)
1156                 if err != nil {
1157                         xapp.Logger.Error("Failed to send RIC_SUB_REQ: %v", err)
1158                         log.Printf("Failed to send RIC_SUB_REQ: %v", err)
1159                         return err
1160                 }
1161
1162                 c.setEventCreateExpiredTimer(params.Meid.RanName)
1163                 //c.ranList = append(c.ranList[:index], c.ranList[index+1:]...)
1164                 //index--
1165         }
1166
1167         return nil
1168 }
1169
1170 func (c *Control) sendRicSubDelRequest(subID int, requestSN int, funcID int) (err error) {
1171         params := &xapp.RMRParams{}
1172         params.Mtype = 12020
1173         params.SubId = subID
1174         var e2ap *E2ap
1175
1176         params.Payload = make([]byte, 1024)
1177         params.Payload, err = e2ap.SetSubscriptionDeleteRequestPayload(params.Payload, 100, uint16(requestSN), uint16(funcID))
1178         if err != nil {
1179                 xapp.Logger.Error("Failed to send RIC_SUB_DEL_REQ: %v", err)
1180                 return err
1181         }
1182
1183         log.Printf("Set Payload: %x", params.Payload)
1184
1185         if funcID == 0 {
1186                 //params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "0"}
1187                 params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"}
1188         } else {
1189                 //params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "3"}
1190                 params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"}
1191         }
1192
1193         xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1194         log.Printf("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
1195
1196         err = c.rmrSend(params)
1197         if err != nil {
1198                 xapp.Logger.Error("Failed to send RIC_SUB_DEL_REQ: %v", err)
1199                 log.Printf("Failed to send RIC_SUB_DEL_REQ: %v", err)
1200                 return err
1201         }
1202
1203         c.setEventDeleteExpiredTimer(params.Meid.RanName)
1204
1205         return nil
1206 }