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