dee7e65366a3108f3fe14b1873f490b430d2be75
[ric-plt/submgr.git] / pkg / control / control.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package control
21
22 import (
23         "fmt"
24         "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
25         rtmgrclient "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client"
26         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
27         httptransport "github.com/go-openapi/runtime/client"
28         "github.com/go-openapi/strfmt"
29         "github.com/spf13/viper"
30         "sync"
31         "time"
32 )
33
34 //-----------------------------------------------------------------------------
35 //
36 //-----------------------------------------------------------------------------
37
38 var e2tSubReqTimeout time.Duration = 5 * time.Second
39 var e2tSubDelReqTime time.Duration = 5 * time.Second
40 var e2tMaxSubReqTryCount uint64 = 2    // Initial try + retry
41 var e2tMaxSubDelReqTryCount uint64 = 2 // Initial try + retry
42
43 var e2tRecvMsgTimeout time.Duration = 5 * time.Second
44
45 type Control struct {
46         e2ap         *E2ap
47         registry     *Registry
48         tracker      *Tracker
49         timerMap     *TimerMap
50         rmrSendMutex sync.Mutex
51         msgCounter   uint64
52 }
53
54 type RMRMeid struct {
55         PlmnID  string
56         EnbID   string
57         RanName string
58 }
59
60 const (
61         CREATE Action = 0
62         UPDATE Action = 1
63         NONE   Action = 2
64         DELETE Action = 3
65 )
66
67 func init() {
68         xapp.Logger.Info("SUBMGR")
69         viper.AutomaticEnv()
70         viper.SetEnvPrefix("submgr")
71         viper.AllowEmptyEnv(true)
72 }
73
74 func NewControl() *Control {
75
76         transport := httptransport.New(viper.GetString("rtmgr.HostAddr")+":"+viper.GetString("rtmgr.port"), viper.GetString("rtmgr.baseUrl"), []string{"http"})
77         rtmgrClient := RtmgrClient{rtClient: rtmgrclient.New(transport, strfmt.Default)}
78
79         registry := new(Registry)
80         registry.Initialize()
81         registry.rtmgrClient = &rtmgrClient
82
83         tracker := new(Tracker)
84         tracker.Init()
85
86         timerMap := new(TimerMap)
87         timerMap.Init()
88
89         return &Control{e2ap: new(E2ap),
90                 registry:   registry,
91                 tracker:    tracker,
92                 timerMap:   timerMap,
93                 msgCounter: 0,
94         }
95 }
96
97 func (c *Control) Run() {
98         xapp.Run(c)
99 }
100
101 func (c *Control) rmrSendRaw(desc string, params *RMRParams) (err error) {
102
103         xapp.Logger.Info("%s: %s", desc, params.String())
104         status := false
105         i := 1
106         for ; i <= 10 && status == false; i++ {
107                 c.rmrSendMutex.Lock()
108                 status = xapp.Rmr.Send(params.RMRParams, false)
109                 c.rmrSendMutex.Unlock()
110                 if status == false {
111                         xapp.Logger.Info("rmr.Send() failed. Retry count %d, %s", i, params.String())
112                         time.Sleep(500 * time.Millisecond)
113                 }
114         }
115         if status == false {
116                 err = fmt.Errorf("rmr.Send() failed. Retry count %d, %s", i, params.String())
117                 xapp.Logger.Error("%s: %s", desc, err.Error())
118                 xapp.Rmr.Free(params.Mbuf)
119         }
120         return
121 }
122
123 func (c *Control) rmrSend(desc string, subs *Subscription, trans *Transaction) (err error) {
124         params := &RMRParams{&xapp.RMRParams{}}
125         params.Mtype = trans.GetMtype()
126         params.SubId = int(subs.GetSubId())
127         params.Xid = ""
128         params.Meid = subs.GetMeid()
129         params.Src = ""
130         params.PayloadLen = len(trans.Payload.Buf)
131         params.Payload = trans.Payload.Buf
132         params.Mbuf = nil
133
134         return c.rmrSendRaw(desc, params)
135 }
136
137 func (c *Control) rmrReplyToSender(desc string, subs *Subscription, trans *Transaction) (err error) {
138         params := &RMRParams{&xapp.RMRParams{}}
139         params.Mtype = trans.GetMtype()
140         params.SubId = int(subs.GetSubId())
141         params.Xid = trans.GetXid()
142         params.Meid = trans.GetMeid()
143         params.Src = ""
144         params.PayloadLen = len(trans.Payload.Buf)
145         params.Payload = trans.Payload.Buf
146         params.Mbuf = nil
147
148         return c.rmrSendRaw(desc, params)
149 }
150
151 func (c *Control) Consume(params *xapp.RMRParams) (err error) {
152         xapp.Rmr.Free(params.Mbuf)
153         params.Mbuf = nil
154         msg := &RMRParams{params}
155         c.msgCounter++
156         switch msg.Mtype {
157         case xapp.RICMessageTypes["RIC_SUB_REQ"]:
158                 go c.handleXAPPSubscriptionRequest(msg)
159         case xapp.RICMessageTypes["RIC_SUB_RESP"]:
160                 go c.handleE2TSubscriptionResponse(msg)
161         case xapp.RICMessageTypes["RIC_SUB_FAILURE"]:
162                 go c.handleE2TSubscriptionFailure(msg)
163         case xapp.RICMessageTypes["RIC_SUB_DEL_REQ"]:
164                 go c.handleXAPPSubscriptionDeleteRequest(msg)
165         case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]:
166                 go c.handleE2TSubscriptionDeleteResponse(msg)
167         case xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]:
168                 go c.handleE2TSubscriptionDeleteFailure(msg)
169         default:
170                 xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
171         }
172
173         return nil
174 }
175 func idstring(trans fmt.Stringer, subs fmt.Stringer, err error) string {
176         var retval string = ""
177         var filler string = ""
178         if trans != nil {
179                 retval += filler + trans.String()
180                 filler = " "
181         }
182         if subs != nil {
183                 retval += filler + subs.String()
184                 filler = " "
185         }
186         if err != nil {
187                 retval += filler + "err(" + err.Error() + ")"
188                 filler = " "
189
190         }
191         return retval
192 }
193
194 //-------------------------------------------------------------------
195 // handle from XAPP Subscription Request
196 //------------------------------------------------------------------
197 func (c *Control) handleXAPPSubscriptionRequest(params *RMRParams) {
198         xapp.Logger.Info("XAPP-SubReq from xapp: %s", params.String())
199
200         subReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload)
201         if err != nil {
202                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(params, nil, err))
203                 return
204         }
205
206         trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src), params.Xid, params.Meid)
207         if err != nil {
208                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(params, nil, err))
209                 return
210         }
211         defer trans.Release()
212
213         subs, err := c.registry.AssignToSubscription(trans, subReqMsg)
214         if err != nil {
215                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(trans, nil, err))
216                 return
217         }
218
219         //
220         // Wake subs request
221         //
222         go c.handleSubscriptionCreate(subs, trans)
223         event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
224
225         err = nil
226         if event != nil {
227                 switch themsg := event.(type) {
228                 case *e2ap.E2APSubscriptionResponse:
229                         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionResponse(themsg)
230                         if err == nil {
231                                 c.rmrReplyToSender("XAPP-SubReq: SubResp to xapp", subs, trans)
232                                 return
233                         }
234                 case *e2ap.E2APSubscriptionFailure:
235                         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionFailure(themsg)
236                         if err == nil {
237                                 c.rmrReplyToSender("XAPP-SubReq: SubFail to xapp", subs, trans)
238                         }
239                         return
240                 default:
241                         break
242                 }
243         }
244         xapp.Logger.Info("XAPP-SubReq: failed %s", idstring(trans, subs, err))
245 }
246
247 //-------------------------------------------------------------------
248 // handle from XAPP Subscription Delete Request
249 //------------------------------------------------------------------
250 func (c *Control) handleXAPPSubscriptionDeleteRequest(params *RMRParams) {
251         xapp.Logger.Info("XAPP-SubDelReq from xapp: %s", params.String())
252
253         subDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
254         if err != nil {
255                 xapp.Logger.Error("XAPP-SubDelReq %s", idstring(params, nil, err))
256                 return
257         }
258
259         trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src), params.Xid, params.Meid)
260         if err != nil {
261                 xapp.Logger.Error("XAPP-SubDelReq %s", idstring(params, nil, err))
262                 return
263         }
264         defer trans.Release()
265
266         subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subDelReqMsg.RequestId.Seq), uint16(params.SubId)})
267         if err != nil {
268                 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(trans, nil, err))
269                 return
270         }
271
272         //
273         // Wake subs delete
274         //
275         go c.handleSubscriptionDelete(subs, trans)
276         trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
277
278         // Whatever is received send ok delete response
279         subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{}
280         subDelRespMsg.RequestId.Id = subs.SubReqMsg.RequestId.Id
281         subDelRespMsg.RequestId.Seq = uint32(subs.GetSubId())
282         subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId
283         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteResponse(subDelRespMsg)
284         if err == nil {
285                 c.rmrReplyToSender("XAPP-SubDelReq: SubDelResp to xapp", subs, trans)
286         }
287 }
288
289 //-------------------------------------------------------------------
290 // SUBS CREATE Handling
291 //-------------------------------------------------------------------
292 func (c *Control) handleSubscriptionCreate(subs *Subscription, parentTrans *Transaction) {
293
294         trans := c.tracker.NewTransaction(subs.GetMeid())
295         subs.WaitTransactionTurn(trans)
296         defer subs.ReleaseTransactionTurn(trans)
297         defer trans.Release()
298
299         xapp.Logger.Debug("SUBS-SubReq: Handling %s parent %s", idstring(trans, subs, nil), parentTrans.String())
300
301         subs.mutex.Lock()
302         if subs.SubRespMsg != nil {
303                 xapp.Logger.Debug("SUBS-SubReq: Handling (immediate resp response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
304                 parentTrans.SendEvent(subs.SubRespMsg, 0)
305                 subs.mutex.Unlock()
306                 return
307         }
308         if subs.SubFailMsg != nil {
309                 xapp.Logger.Debug("SUBS-SubReq: Handling (immediate fail response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
310                 parentTrans.SendEvent(subs.SubFailMsg, 0)
311                 subs.mutex.Unlock()
312                 go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
313                 return
314         }
315         if subs.valid == false {
316                 xapp.Logger.Debug("SUBS-SubReq: Handling (immediate nil response) %s parent %s", idstring(nil, subs, nil), parentTrans.String())
317                 parentTrans.SendEvent(nil, 0)
318                 subs.mutex.Unlock()
319                 go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
320                 return
321         }
322         subs.mutex.Unlock()
323
324         event := c.sendE2TSubscriptionRequest(subs, trans, parentTrans)
325         switch themsg := event.(type) {
326         case *e2ap.E2APSubscriptionResponse:
327                 subs.mutex.Lock()
328                 subs.SubRespMsg = themsg
329                 subs.mutex.Unlock()
330                 parentTrans.SendEvent(event, 0)
331                 return
332         case *e2ap.E2APSubscriptionFailure:
333                 subs.mutex.Lock()
334                 subs.SubFailMsg = themsg
335                 subs.mutex.Unlock()
336                 parentTrans.SendEvent(event, 0)
337         default:
338                 xapp.Logger.Info("SUBS-SubReq: internal delete due event(%s) %s", typeofSubsMessage(event), idstring(trans, subs, nil))
339                 subs.mutex.Lock()
340                 subs.valid = false
341                 subs.mutex.Unlock()
342                 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
343                 parentTrans.SendEvent(nil, 0)
344         }
345
346         go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
347 }
348
349 //-------------------------------------------------------------------
350 // SUBS DELETE Handling
351 //-------------------------------------------------------------------
352
353 func (c *Control) handleSubscriptionDelete(subs *Subscription, parentTrans *Transaction) {
354
355         trans := c.tracker.NewTransaction(subs.GetMeid())
356         subs.WaitTransactionTurn(trans)
357         defer subs.ReleaseTransactionTurn(trans)
358         defer trans.Release()
359
360         xapp.Logger.Debug("SUBS-SubDelReq: Handling %s parent %s", idstring(trans, subs, nil), parentTrans.String())
361
362         subs.mutex.Lock()
363         if subs.valid && subs.EpList.HasEndpoint(parentTrans.GetEndpoint()) && subs.EpList.Size() == 1 {
364                 subs.valid = false
365                 subs.mutex.Unlock()
366                 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
367         } else {
368                 subs.mutex.Unlock()
369         }
370
371         subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{}
372         subDelRespMsg.RequestId.Id = subs.SubReqMsg.RequestId.Id
373         subDelRespMsg.RequestId.Seq = uint32(subs.GetSubId())
374         subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId
375         parentTrans.SendEvent(subDelRespMsg, 0)
376
377         go c.registry.RemoveFromSubscription(subs, parentTrans, 5*time.Second)
378 }
379
380 //-------------------------------------------------------------------
381 // send to E2T Subscription Request
382 //-------------------------------------------------------------------
383 func (c *Control) sendE2TSubscriptionRequest(subs *Subscription, trans *Transaction, parentTrans *Transaction) interface{} {
384         var err error
385         var event interface{} = nil
386         var timedOut bool = false
387
388         subReqMsg := subs.SubReqMsg
389         subReqMsg.RequestId.Id = 123
390         subReqMsg.RequestId.Seq = uint32(subs.GetSubId())
391         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionRequest(subReqMsg)
392         if err != nil {
393                 xapp.Logger.Error("SUBS-SubReq: %s parent %s", idstring(trans, subs, err), parentTrans.String())
394                 return event
395         }
396
397         for retries := uint64(0); retries < e2tMaxSubReqTryCount; retries++ {
398                 desc := fmt.Sprintf("SUBS-SubReq: SubReq to E2T (retry %d)", retries)
399                 c.rmrSend(desc, subs, trans)
400                 event, timedOut = trans.WaitEvent(e2tSubReqTimeout)
401                 if timedOut {
402                         continue
403                 }
404                 break
405         }
406         xapp.Logger.Debug("SUBS-SubReq: Response handling event(%s) %s parent %s", typeofSubsMessage(event), idstring(trans, subs, nil), parentTrans.String())
407         return event
408 }
409
410 //-------------------------------------------------------------------
411 // send to E2T Subscription Delete Request
412 //-------------------------------------------------------------------
413
414 func (c *Control) sendE2TSubscriptionDeleteRequest(subs *Subscription, trans *Transaction, parentTrans *Transaction) interface{} {
415         var err error
416         var event interface{}
417         var timedOut bool
418
419         subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{}
420         subDelReqMsg.RequestId.Id = 123
421         subDelReqMsg.RequestId.Seq = uint32(subs.GetSubId())
422         subDelReqMsg.FunctionId = subs.SubReqMsg.FunctionId
423         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg)
424         if err != nil {
425                 xapp.Logger.Error("SUBS-SubDelReq: %s parent %s", idstring(trans, subs, err), parentTrans.String())
426                 return event
427         }
428
429         for retries := uint64(0); retries < e2tMaxSubDelReqTryCount; retries++ {
430                 desc := fmt.Sprintf("SUBS-SubDelReq: SubDelReq to E2T (retry %d)", retries)
431                 c.rmrSend(desc, subs, trans)
432                 event, timedOut = trans.WaitEvent(e2tSubDelReqTime)
433                 if timedOut {
434                         continue
435                 }
436                 break
437         }
438         xapp.Logger.Debug("SUBS-SubDelReq: Response handling event(%s) %s parent %s", typeofSubsMessage(event), idstring(trans, subs, nil), parentTrans.String())
439         return event
440 }
441
442 //-------------------------------------------------------------------
443 // handle from E2T Subscription Reponse
444 //-------------------------------------------------------------------
445 func (c *Control) handleE2TSubscriptionResponse(params *RMRParams) {
446         xapp.Logger.Info("MSG-SubResp from E2T: %s", params.String())
447         subRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload)
448         if err != nil {
449                 xapp.Logger.Error("MSG-SubResp %s", idstring(params, nil, err))
450                 return
451         }
452         subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subRespMsg.RequestId.Seq), uint16(params.SubId)})
453         if err != nil {
454                 xapp.Logger.Error("MSG-SubResp: %s", idstring(params, nil, err))
455                 return
456         }
457         trans := subs.GetTransaction()
458         if trans == nil {
459                 err = fmt.Errorf("Ongoing transaction not found")
460                 xapp.Logger.Error("MSG-SubResp: %s", idstring(params, subs, err))
461                 return
462         }
463         sendOk, timedOut := trans.SendEvent(subRespMsg, e2tRecvMsgTimeout)
464         if sendOk == false {
465                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
466                 xapp.Logger.Error("MSG-SubResp: %s", idstring(trans, subs, err))
467         }
468         return
469 }
470
471 //-------------------------------------------------------------------
472 // handle from E2T Subscription Failure
473 //-------------------------------------------------------------------
474 func (c *Control) handleE2TSubscriptionFailure(params *RMRParams) {
475         xapp.Logger.Info("MSG-SubFail from E2T: %s", params.String())
476         subFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload)
477         if err != nil {
478                 xapp.Logger.Error("MSG-SubFail %s", idstring(params, nil, err))
479                 return
480         }
481         subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subFailMsg.RequestId.Seq), uint16(params.SubId)})
482         if err != nil {
483                 xapp.Logger.Error("MSG-SubFail: %s", idstring(params, nil, err))
484                 return
485         }
486         trans := subs.GetTransaction()
487         if trans == nil {
488                 err = fmt.Errorf("Ongoing transaction not found")
489                 xapp.Logger.Error("MSG-SubFail: %s", idstring(params, subs, err))
490                 return
491         }
492         sendOk, timedOut := trans.SendEvent(subFailMsg, e2tRecvMsgTimeout)
493         if sendOk == false {
494                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
495                 xapp.Logger.Error("MSG-SubFail: %s", idstring(trans, subs, err))
496         }
497         return
498 }
499
500 //-------------------------------------------------------------------
501 // handle from E2T Subscription Delete Response
502 //-------------------------------------------------------------------
503 func (c *Control) handleE2TSubscriptionDeleteResponse(params *RMRParams) (err error) {
504         xapp.Logger.Info("SUBS-SubDelResp from E2T:%s", params.String())
505         subDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload)
506         if err != nil {
507                 xapp.Logger.Error("SUBS-SubDelResp: %s", idstring(params, nil, err))
508                 return
509         }
510         subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subDelRespMsg.RequestId.Seq), uint16(params.SubId)})
511         if err != nil {
512                 xapp.Logger.Error("SUBS-SubDelResp: %s", idstring(params, nil, err))
513                 return
514         }
515         trans := subs.GetTransaction()
516         if trans == nil {
517                 err = fmt.Errorf("Ongoing transaction not found")
518                 xapp.Logger.Error("SUBS-SubDelResp: %s", idstring(params, subs, err))
519                 return
520         }
521         sendOk, timedOut := trans.SendEvent(subDelRespMsg, e2tRecvMsgTimeout)
522         if sendOk == false {
523                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
524                 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(trans, subs, err))
525         }
526         return
527 }
528
529 //-------------------------------------------------------------------
530 // handle from E2T Subscription Delete Failure
531 //-------------------------------------------------------------------
532 func (c *Control) handleE2TSubscriptionDeleteFailure(params *RMRParams) {
533         xapp.Logger.Info("MSG-SubDelFail from E2T:%s", params.String())
534         subDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload)
535         if err != nil {
536                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(params, nil, err))
537                 return
538         }
539         subs, err := c.registry.GetSubscriptionFirstMatch([]uint16{uint16(subDelFailMsg.RequestId.Seq), uint16(params.SubId)})
540         if err != nil {
541                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(params, nil, err))
542                 return
543         }
544         trans := subs.GetTransaction()
545         if trans == nil {
546                 err = fmt.Errorf("Ongoing transaction not found")
547                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(params, subs, err))
548                 return
549         }
550         sendOk, timedOut := trans.SendEvent(subDelFailMsg, e2tRecvMsgTimeout)
551         if sendOk == false {
552                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
553                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(trans, subs, err))
554         }
555         return
556 }
557
558 //-------------------------------------------------------------------
559 //
560 //-------------------------------------------------------------------
561 func typeofSubsMessage(v interface{}) string {
562         if v == nil {
563                 return "NIL"
564         }
565         switch v.(type) {
566         case *e2ap.E2APSubscriptionRequest:
567                 return "SubReq"
568         case *e2ap.E2APSubscriptionResponse:
569                 return "SubResp"
570         case *e2ap.E2APSubscriptionFailure:
571                 return "SubFail"
572         case *e2ap.E2APSubscriptionDeleteRequest:
573                 return "SubDelReq"
574         case *e2ap.E2APSubscriptionDeleteResponse:
575                 return "SubDelResp"
576         case *e2ap.E2APSubscriptionDeleteFailure:
577                 return "SubDelFail"
578         default:
579                 return "Unknown"
580         }
581 }