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