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