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