RICPLT-2980 SubResp go asn into use
[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         rtmgrhandle "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client/handle"
27         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
28         httptransport "github.com/go-openapi/runtime/client"
29         "github.com/go-openapi/strfmt"
30         "github.com/spf13/viper"
31         "math/rand"
32         "sync"
33         "time"
34 )
35
36 //-----------------------------------------------------------------------------
37 //
38 //-----------------------------------------------------------------------------
39
40 var subReqTime time.Duration = 5 * time.Second
41 var subDelReqTime time.Duration = 5 * time.Second
42 var maxSubReqTryCount uint64 = 2    // Initial try + retry
43 var maxSubDelReqTryCount uint64 = 2 // Initial try + retry
44
45 type Control struct {
46         e2ap         *E2ap
47         registry     *Registry
48         rtmgrClient  *RtmgrClient
49         tracker      *Tracker
50         timerMap     *TimerMap
51         rmrSendMutex sync.Mutex
52         msgCounter   uint64
53 }
54
55 type RMRMeid struct {
56         PlmnID  string
57         EnbID   string
58         RanName string
59 }
60
61 var seedSN uint16
62
63 const (
64         CREATE Action = 0
65         MERGE  Action = 1
66         NONE   Action = 2
67         DELETE Action = 3
68 )
69
70 func init() {
71         xapp.Logger.Info("SUBMGR")
72         viper.AutomaticEnv()
73         viper.SetEnvPrefix("submgr")
74         viper.AllowEmptyEnv(true)
75         seedSN = uint16(viper.GetInt("seed_sn"))
76         if seedSN == 0 {
77                 rand.Seed(time.Now().UnixNano())
78                 seedSN = uint16(rand.Intn(65535))
79         }
80         if seedSN > 65535 {
81                 seedSN = 0
82         }
83         xapp.Logger.Info("SUBMGR: Initial Sequence Number: %v", seedSN)
84 }
85
86 func NewControl() *Control {
87
88         registry := new(Registry)
89         registry.Initialize(seedSN)
90
91         tracker := new(Tracker)
92         tracker.Init()
93
94         timerMap := new(TimerMap)
95         timerMap.Init()
96
97         transport := httptransport.New(viper.GetString("rtmgr.HostAddr")+":"+viper.GetString("rtmgr.port"), viper.GetString("rtmgr.baseUrl"), []string{"http"})
98         client := rtmgrclient.New(transport, strfmt.Default)
99         handle := rtmgrhandle.NewProvideXappSubscriptionHandleParamsWithTimeout(10 * time.Second)
100         deleteHandle := rtmgrhandle.NewDeleteXappSubscriptionHandleParamsWithTimeout(10 * time.Second)
101         rtmgrClient := RtmgrClient{client, handle, deleteHandle}
102
103         rtmgrClientPtr := &rtmgrClient
104
105         //TODO: to make this better. Now it is just a hack.
106         registry.rtmgrClient = rtmgrClientPtr
107
108         return &Control{e2ap: new(E2ap),
109                 registry:    registry,
110                 rtmgrClient: rtmgrClientPtr,
111                 tracker:     tracker,
112                 timerMap:    timerMap,
113                 msgCounter:  0,
114         }
115 }
116
117 func (c *Control) Run() {
118         xapp.Run(c)
119 }
120
121 func (c *Control) rmrSendRaw(desc string, params *RMRParams) (err error) {
122
123         xapp.Logger.Info("%s: %s", desc, params.String())
124         status := false
125         i := 1
126         for ; i <= 10 && status == false; i++ {
127                 c.rmrSendMutex.Lock()
128                 status = xapp.Rmr.Send(params.RMRParams, false)
129                 c.rmrSendMutex.Unlock()
130                 if status == false {
131                         xapp.Logger.Info("rmr.Send() failed. Retry count %d, %s", i, params.String())
132                         time.Sleep(500 * time.Millisecond)
133                 }
134         }
135         if status == false {
136                 err = fmt.Errorf("rmr.Send() failed. Retry count %d, %s", i, params.String())
137                 xapp.Logger.Error("%s: %s", desc, err.Error())
138                 xapp.Rmr.Free(params.Mbuf)
139         }
140         return
141 }
142
143 func (c *Control) rmrSend(desc string, subs *Subscription, trans *Transaction, payload []byte, payloadLen int) (err error) {
144         params := &RMRParams{&xapp.RMRParams{}}
145         params.Mtype = trans.GetMtype()
146         params.SubId = int(subs.GetSubId())
147         params.Xid = ""
148         params.Meid = subs.GetMeid()
149         params.Src = ""
150         params.PayloadLen = payloadLen
151         params.Payload = payload
152         params.Mbuf = nil
153
154         return c.rmrSendRaw(desc, params)
155 }
156
157 func (c *Control) rmrReplyToSender(desc string, subs *Subscription, trans *Transaction, mType int, payload []byte, payloadLen int) (err error) {
158         params := &RMRParams{&xapp.RMRParams{}}
159         params.Mtype = mType
160         params.SubId = int(subs.GetSubId())
161         params.Xid = trans.GetXid()
162         params.Meid = trans.GetMeid()
163         params.Src = ""
164         params.PayloadLen = payloadLen
165         params.Payload = payload
166         params.Mbuf = nil
167
168         return c.rmrSendRaw(desc, params)
169 }
170
171 func (c *Control) Consume(params *xapp.RMRParams) (err error) {
172         xapp.Rmr.Free(params.Mbuf)
173         params.Mbuf = nil
174         msg := &RMRParams{params}
175         c.msgCounter++
176         switch msg.Mtype {
177         case xapp.RICMessageTypes["RIC_SUB_REQ"]:
178                 go c.handleSubscriptionRequest(msg)
179         case xapp.RICMessageTypes["RIC_SUB_RESP"]:
180                 go c.handleSubscriptionResponse(msg)
181         case xapp.RICMessageTypes["RIC_SUB_FAILURE"]:
182                 go c.handleSubscriptionFailure(msg)
183         case xapp.RICMessageTypes["RIC_SUB_DEL_REQ"]:
184                 go c.handleSubscriptionDeleteRequest(msg)
185         case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]:
186                 go c.handleSubscriptionDeleteResponse(msg)
187         case xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]:
188                 go c.handleSubscriptionDeleteFailure(msg)
189         default:
190                 xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
191         }
192
193         return nil
194 }
195
196 func (c *Control) handleSubscriptionRequest(params *RMRParams) {
197         xapp.Logger.Info("SubReq from xapp: %s", params.String())
198
199         //
200         //
201         //
202         trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src),
203                 params.Mtype,
204                 params.Xid,
205                 params.Meid,
206                 false,
207                 true)
208
209         if err != nil {
210                 xapp.Logger.Error("SubReq: %s, Dropping this msg. %s", err.Error(), params.String())
211                 return
212         }
213
214         //
215         //
216         //
217         trans.SubReqMsg, err = c.e2ap.UnpackSubscriptionRequest(params.Payload)
218         if err != nil {
219                 xapp.Logger.Error("SubReq: %s Dropping this msg. %s", err.Error(), trans)
220                 trans.Release()
221                 return
222         }
223
224         //
225         //
226         //
227         subs, err := c.registry.ReserveSubscription(&trans.RmrEndpoint, trans.Meid)
228         if err != nil {
229                 xapp.Logger.Error("SubReq: %s, Dropping this msg. %s", err.Error(), trans)
230                 trans.Release()
231                 return
232         }
233
234         err = subs.SetTransaction(trans)
235         if err != nil {
236                 xapp.Logger.Error("SubReq: %s, Dropping this msg. %s", err.Error(), trans)
237                 c.registry.DelSubscription(subs.Seq)
238                 trans.Release()
239                 return
240         }
241
242         trans.SubReqMsg.RequestId.Seq = uint32(subs.GetSubId())
243
244         //
245         // TODO: subscription create is in fact owned by subscription and not transaction.
246         //       Transaction is toward xapp while Subscription is toward ran.
247         //       In merge several xapps may wake transactions, while only one subscription
248         //       toward ran occurs -> subscription owns subscription creation toward ran
249         //
250         //       This is intermediate solution while improving message handling
251         //
252         packedData, err := c.e2ap.PackSubscriptionRequest(trans.SubReqMsg)
253         if err != nil {
254                 xapp.Logger.Error("SubReq: %s for trans %s", err.Error(), trans)
255                 c.registry.DelSubscription(subs.Seq)
256                 trans.Release()
257                 return
258         }
259
260         //Optimize and store packed message to be sent (for retransmission). Again owned by subscription?
261         trans.Payload = packedData.Buf
262         trans.PayloadLen = len(packedData.Buf)
263
264         c.rmrSend("SubReq to E2T", subs, trans, packedData.Buf, len(packedData.Buf))
265
266         c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.GetSubId()), subReqTime, FirstTry, c.handleSubscriptionRequestTimer)
267         xapp.Logger.Debug("SubReq: Debugging trans table = %v", c.tracker.transactionXappTable)
268         return
269 }
270
271 func (c *Control) handleSubscriptionResponse(params *RMRParams) {
272         xapp.Logger.Info("SubResp from E2T: %s", params.String())
273
274         //
275         //
276         //
277         SubRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload)
278         if err != nil {
279                 xapp.Logger.Error("SubDelReq: %s Dropping this msg. %s", err.Error(), params.String())
280                 return
281         }
282
283         //
284         //
285         //
286         subs := c.registry.GetSubscription(uint16(SubRespMsg.RequestId.Seq))
287         if subs == nil && params.SubId > 0 {
288                 subs = c.registry.GetSubscription(uint16(params.SubId))
289         }
290
291         if subs == nil {
292                 xapp.Logger.Error("SubResp: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", SubRespMsg.RequestId.Seq, params.SubId, params.String())
293                 return
294         }
295         xapp.Logger.Info("SubResp: subscription found payloadSeqNum: %d, SubId: %d", SubRespMsg.RequestId.Seq, subs.GetSubId())
296
297         //
298         //
299         //
300         trans := subs.GetTransaction()
301         if trans == nil {
302                 xapp.Logger.Error("SubResp: Unknown trans. Dropping this msg. SubId: %d", subs.GetSubId())
303                 return
304         }
305
306         trans.SubRespMsg = SubRespMsg
307
308         //
309         //
310         //
311         c.timerMap.StopTimer("RIC_SUB_REQ", int(subs.GetSubId()))
312
313         responseReceived := trans.CheckResponseReceived()
314         if responseReceived == true {
315                 // Subscription timer already received
316                 return
317         }
318
319         packedData, err := c.e2ap.PackSubscriptionResponse(trans.SubRespMsg)
320         if err != nil {
321                 xapp.Logger.Error("SubResp: %s for trans %s", err.Error(), trans)
322                 trans.Release()
323                 return
324         }
325
326         //Optimize and store packed message to be sent.
327         trans.Payload = packedData.Buf
328         trans.PayloadLen = len(packedData.Buf)
329
330         subs.Confirmed()
331         trans.Release()
332         c.rmrReplyToSender("SubResp to xapp", subs, trans, 12011, trans.Payload, trans.PayloadLen)
333         return
334 }
335
336 func (c *Control) handleSubscriptionFailure(params *RMRParams) {
337         xapp.Logger.Info("SubFail from E2T: %s", params.String())
338
339         payloadSeqNum, err := c.e2ap.GetSubscriptionFailureSequenceNumber(params.Payload)
340         if err != nil {
341                 xapp.Logger.Error("SubFail: Unable to get Sequence Number from Payload. Dropping this msg. Err: %v, SubId: %v, Xid: %s, Payload %X", err, params.SubId, params.Xid, params.Payload)
342                 return
343         }
344         xapp.Logger.Info("SubFail: Received payloadSeqNum: %v", payloadSeqNum)
345
346         subs := c.registry.GetSubscription(payloadSeqNum)
347         if subs == nil {
348                 xapp.Logger.Error("SubFail: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
349                 return
350         }
351
352         trans := subs.GetTransaction()
353         if trans == nil {
354                 xapp.Logger.Error("SubFail: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
355                 return
356         }
357
358         c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum))
359
360         responseReceived := trans.CheckResponseReceived()
361         if err != nil {
362                 xapp.Logger.Info("SubFail: Dropping this msg. Err: %v SubId: %v", err, payloadSeqNum)
363                 return
364         }
365
366         if responseReceived == true {
367                 // Subscription timer already received
368                 return
369         }
370         xapp.Logger.Info("SubFail: SubId: %v, from address: %s. Forwarding response to xApp", payloadSeqNum, trans.RmrEndpoint)
371
372         c.rmrReplyToSender("SubFail to xapp", subs, trans, params.Mtype, params.Payload, params.PayloadLen)
373
374         time.Sleep(3 * time.Second)
375
376         xapp.Logger.Info("SubFail: Deleting trans record. SubId: %v, Xid: %s", params.SubId, params.Xid)
377         trans.Release()
378         if !c.registry.DelSubscription(payloadSeqNum) {
379                 xapp.Logger.Error("SubFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid)
380         }
381         return
382 }
383
384 func (c *Control) handleSubscriptionRequestTimer(strId string, nbrId int, tryCount uint64) {
385         xapp.Logger.Info("SubReq timeout: subId: %v,  tryCount: %v", nbrId, tryCount)
386
387         subs := c.registry.GetSubscription(uint16(nbrId))
388         if subs == nil {
389                 xapp.Logger.Error("SubReq timeout: Unknown payloadSeqNum. Dropping this msg. SubId: %v", nbrId)
390                 return
391         }
392
393         trans := subs.GetTransaction()
394         if trans == nil {
395                 xapp.Logger.Error("SubReq timeout: Unknown trans. Dropping this msg. SubId: %v", subs.GetSubId())
396                 return
397         }
398
399         responseReceived := trans.CheckResponseReceived()
400
401         if responseReceived == true {
402                 // Subscription Response or Failure already received
403                 return
404         }
405
406         if tryCount < maxSubReqTryCount {
407                 xapp.Logger.Info("SubReq timeout: Resending SubReq to E2T: Mtype: %v, SubId: %v, Xid %s, Meid %v", trans.GetMtype(), subs.GetSubId(), trans.GetXid(), trans.GetMeid())
408
409                 trans.RetryTransaction()
410
411                 c.rmrSend("SubReq(SubReq timer) to E2T", subs, trans, trans.Payload, trans.PayloadLen)
412
413                 tryCount++
414                 c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionRequestTimer)
415                 return
416         }
417
418         // Delete CREATE transaction
419         trans.Release()
420
421         // Create DELETE transaction (internal and no messages toward xapp)
422         deltrans, err := c.tracker.TrackTransaction(&trans.RmrEndpoint,
423                 12020, // RIC SUBSCRIPTION DELETE
424                 trans.GetXid(),
425                 trans.GetMeid(),
426                 false,
427                 false)
428
429         if err != nil {
430                 xapp.Logger.Error("SubReq timeout: %s, Dropping this msg.", err.Error())
431                 //TODO improve error handling. Important at least in merge
432                 c.registry.DelSubscription(subs.GetSubId())
433                 return
434         }
435
436         deltrans.SubDelReqMsg = &e2ap.E2APSubscriptionDeleteRequest{}
437         deltrans.SubDelReqMsg.RequestId.Id = trans.SubReqMsg.RequestId.Id
438         deltrans.SubDelReqMsg.RequestId.Seq = uint32(subs.GetSubId())
439         deltrans.SubDelReqMsg.FunctionId = trans.SubReqMsg.FunctionId
440         packedData, err := c.e2ap.PackSubscriptionDeleteRequest(deltrans.SubDelReqMsg)
441         if err != nil {
442                 xapp.Logger.Error("SubReq timeout: Packing SubDelReq failed. Err: %v", err)
443                 //TODO improve error handling. Important at least in merge
444                 deltrans.Release()
445                 c.registry.DelSubscription(subs.GetSubId())
446                 return
447         }
448         deltrans.PayloadLen = len(packedData.Buf)
449         deltrans.Payload = packedData.Buf
450
451         err = subs.SetTransaction(deltrans)
452         if err != nil {
453                 xapp.Logger.Error("SubReq timeout: %s, Dropping this msg.", err.Error())
454                 //TODO improve error handling. Important at least in merge
455                 deltrans.Release()
456                 return
457         }
458
459         c.rmrSend("SubDelReq(SubReq timer) to E2T", subs, deltrans, deltrans.Payload, deltrans.PayloadLen)
460
461         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
462         return
463 }
464
465 func (c *Control) handleSubscriptionDeleteRequest(params *RMRParams) {
466         xapp.Logger.Info("SubDelReq from xapp: %s", params.String())
467
468         //
469         //
470         //
471         trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src),
472                 params.Mtype,
473                 params.Xid,
474                 params.Meid,
475                 false,
476                 true)
477
478         if err != nil {
479                 xapp.Logger.Error("SubDelReq: %s, Dropping this msg. %s", err.Error(), params.String())
480                 return
481         }
482
483         //
484         //
485         //
486         trans.SubDelReqMsg, err = c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
487         if err != nil {
488                 xapp.Logger.Error("SubDelReq: %s Dropping this msg. %s", err.Error(), trans)
489                 trans.Release()
490                 return
491         }
492
493         //
494         //
495         //
496         subs := c.registry.GetSubscription(uint16(trans.SubDelReqMsg.RequestId.Seq))
497         if subs == nil && params.SubId > 0 {
498                 subs = c.registry.GetSubscription(uint16(params.SubId))
499         }
500
501         if subs == nil {
502                 xapp.Logger.Error("SubDelReq: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", trans.SubDelReqMsg.RequestId.Seq, params.SubId, trans)
503                 trans.Release()
504                 return
505         }
506         xapp.Logger.Info("SubDelReq: subscription found payloadSeqNum: %d, SubId: %d. %s", trans.SubDelReqMsg.RequestId.Seq, params.SubId, trans)
507
508         err = subs.SetTransaction(trans)
509         if err != nil {
510                 xapp.Logger.Error("SubDelReq: %s, Dropping this msg. %s", err.Error(), trans)
511                 trans.Release()
512                 return
513         }
514
515         //
516         // TODO: subscription delete is in fact owned by subscription and not transaction.
517         //       Transaction is toward xapp while Subscription is toward ran.
518         //       In merge several xapps may wake transactions, while only one subscription
519         //       toward ran occurs -> subscription owns subscription creation toward ran
520         //
521         //       This is intermediate solution while improving message handling
522         //
523         packedData, err := c.e2ap.PackSubscriptionDeleteRequest(trans.SubDelReqMsg)
524         if err != nil {
525                 xapp.Logger.Error("SubDelReq: %s for trans %s", err.Error(), trans)
526                 trans.Release()
527                 return
528         }
529
530         //Optimize and store packed message to be sent (for retransmission). Again owned by subscription?
531         trans.Payload = packedData.Buf
532         trans.PayloadLen = len(packedData.Buf)
533
534         subs.UnConfirmed()
535
536         c.rmrSend("SubDelReq to E2T", subs, trans, trans.Payload, trans.PayloadLen)
537
538         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
539         return
540 }
541
542 func (c *Control) handleSubscriptionDeleteResponse(params *RMRParams) (err error) {
543         xapp.Logger.Info("SubDelResp from E2T:%s", params.String())
544
545         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteResponseSequenceNumber(params.Payload)
546         if err != nil {
547                 xapp.Logger.Error("SubDelResp: Unable to get Sequence Number from Payload. Dropping this msg. Err: %v, SubId: %v, Xid: %s, Payload %X", err, params.SubId, params.Xid, params.Payload)
548                 return
549         }
550         xapp.Logger.Info("SubDelResp: Received payloadSeqNum: %v", payloadSeqNum)
551
552         subs := c.registry.GetSubscription(payloadSeqNum)
553         if subs == nil {
554                 xapp.Logger.Error("SubDelResp: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
555                 return
556         }
557
558         trans := subs.GetTransaction()
559         if trans == nil {
560                 xapp.Logger.Error("SubDelResp: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", subs.GetSubId(), params.SubId)
561                 return
562         }
563
564         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
565
566         responseReceived := trans.CheckResponseReceived()
567         if responseReceived == true {
568                 // Subscription Delete timer already received
569                 return
570         }
571
572         trans.Release()
573
574         if trans.ForwardRespToXapp == true {
575                 c.rmrReplyToSender("SubDelResp to xapp", subs, trans, params.Mtype, params.Payload, params.PayloadLen)
576                 time.Sleep(3 * time.Second)
577         }
578
579         xapp.Logger.Info("SubDelResp: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
580         if !c.registry.DelSubscription(subs.GetSubId()) {
581                 xapp.Logger.Error("SubDelResp: Failed to release sequency number. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
582                 return
583         }
584         return
585 }
586
587 func (c *Control) handleSubscriptionDeleteFailure(params *RMRParams) {
588         xapp.Logger.Info("SubDelFail from E2T:%s", params.String())
589
590         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteFailureSequenceNumber(params.Payload)
591         if err != nil {
592                 xapp.Logger.Error("SubDelFail: Unable to get Sequence Number from Payload. Dropping this msg. Err: %v, %s", err, params.String())
593                 return
594         }
595         xapp.Logger.Info("SubDelFail: Received payloadSeqNum: %v", payloadSeqNum)
596
597         subs := c.registry.GetSubscription(payloadSeqNum)
598         if subs == nil {
599                 xapp.Logger.Error("SubDelFail: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
600                 return
601         }
602
603         trans := subs.GetTransaction()
604         if trans == nil {
605                 xapp.Logger.Error("SubDelFail: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", subs.GetSubId(), params.SubId)
606                 return
607         }
608
609         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
610
611         responseReceived := trans.CheckResponseReceived()
612         if responseReceived == true {
613                 // Subscription Delete timer already received
614                 return
615         }
616         if trans.ForwardRespToXapp == true {
617                 var subDelRespPayload []byte
618                 subDelRespPayload, err = c.e2ap.PackSubscriptionDeleteResponseFromSubDelReq(trans.Payload, subs.GetSubId())
619                 if err != nil {
620                         xapp.Logger.Error("SubDelFail:Packing SubDelResp failed. Err: %v", err)
621                         return
622                 }
623
624                 // RIC SUBSCRIPTION DELETE RESPONSE
625                 c.rmrReplyToSender("SubDelFail to xapp", subs, trans, 12021, subDelRespPayload, len(subDelRespPayload))
626                 time.Sleep(3 * time.Second)
627         }
628
629         xapp.Logger.Info("SubDelFail: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
630         trans.Release()
631         if !c.registry.DelSubscription(subs.GetSubId()) {
632                 xapp.Logger.Error("SubDelFail: Failed to release sequency number. Err: %v, SubId: %v, Xid: %s", err, subs.GetSubId(), trans.GetXid())
633                 return
634         }
635         return
636 }
637
638 func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int, tryCount uint64) {
639         xapp.Logger.Info("SubDelReq timeout: subId: %v, tryCount: %v", nbrId, tryCount)
640
641         subs := c.registry.GetSubscription(uint16(nbrId))
642         if subs == nil {
643                 xapp.Logger.Error("SubDelReq timeout: Unknown payloadSeqNum. Dropping this msg. SubId: %v", nbrId)
644                 return
645         }
646
647         trans := subs.GetTransaction()
648         if trans == nil {
649                 xapp.Logger.Error("SubDelReq timeout: Unknown trans. Dropping this msg. SubId: %v", subs.GetSubId())
650                 return
651         }
652
653         responseReceived := trans.CheckResponseReceived()
654         if responseReceived == true {
655                 // Subscription Delete Response or Failure already received
656                 return
657         }
658
659         if tryCount < maxSubDelReqTryCount {
660                 xapp.Logger.Info("SubDelReq timeout: Resending SubDelReq to E2T: Mtype: %v, SubId: %v, Xid %s, Meid %v", trans.GetMtype(), subs.GetSubId(), trans.GetXid(), trans.GetMeid())
661                 // Set possible to handle new response for the subId
662
663                 trans.RetryTransaction()
664
665                 c.rmrSend("SubDelReq(SubDelReq timer) to E2T", subs, trans, trans.Payload, trans.PayloadLen)
666
667                 tryCount++
668                 c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionDeleteRequestTimer)
669                 return
670         }
671
672         if trans.ForwardRespToXapp == true {
673                 var subDelRespPayload []byte
674                 subDelRespPayload, err := c.e2ap.PackSubscriptionDeleteResponseFromSubDelReq(trans.Payload, subs.GetSubId())
675                 if err != nil {
676                         xapp.Logger.Error("SubDelReq timeout: Unable to pack payload. Dropping this this msg. Err: %v, SubId: %v, Xid: %s, Payload %x", err, subs.GetSubId(), trans.GetXid(), trans.Payload)
677                         return
678                 }
679
680                 // RIC SUBSCRIPTION DELETE RESPONSE
681                 c.rmrReplyToSender("SubDelResp(SubDelReq timer) to xapp", subs, trans, 12021, subDelRespPayload, len(subDelRespPayload))
682
683                 time.Sleep(3 * time.Second)
684
685         }
686
687         xapp.Logger.Info("SubDelReq timeout: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
688         trans.Release()
689         if !c.registry.DelSubscription(subs.GetSubId()) {
690                 xapp.Logger.Error("SubDelReq timeout: Failed to release sequency number. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
691         }
692         return
693 }