RICPLT-2962 Preparation for subs merge
[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/packer"
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 = trans.GetXid()
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 = subs.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
175         msg := &RMRParams{params}
176
177         c.msgCounter++
178
179         switch msg.Mtype {
180         case xapp.RICMessageTypes["RIC_SUB_REQ"]:
181                 go c.handleSubscriptionRequest(msg)
182         case xapp.RICMessageTypes["RIC_SUB_RESP"]:
183                 go c.handleSubscriptionResponse(msg)
184         case xapp.RICMessageTypes["RIC_SUB_FAILURE"]:
185                 go c.handleSubscriptionFailure(msg)
186         case xapp.RICMessageTypes["RIC_SUB_DEL_REQ"]:
187                 go c.handleSubscriptionDeleteRequest(msg)
188         case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]:
189                 go c.handleSubscriptionDeleteResponse(msg)
190         case xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]:
191                 go c.handleSubscriptionDeleteFailure(msg)
192         default:
193                 xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
194         }
195         return nil
196 }
197
198 func (c *Control) handleSubscriptionRequest(params *RMRParams) {
199         xapp.Logger.Info("SubReq from xapp: %s", params.String())
200
201         srcAddr, srcPort, err := c.rtmgrClient.SplitSource(params.Src)
202         if err != nil {
203                 xapp.Logger.Error("SubReq: Failed to update routing-manager. Dropping this msg. Err: %s, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
204                 return
205         }
206
207         subs, err := c.registry.ReserveSubscription(RmrEndpoint{*srcAddr, *srcPort}, params.Meid)
208         if err != nil {
209                 xapp.Logger.Error("SubReq: %s, Dropping this msg.", err.Error())
210                 return
211         }
212
213         //
214         // WIP RICPLT-2979
215         //
216         /*
217                 e2SubReq := packerif.NewPackerSubscriptionRequest()
218                 packedData := &packer.PackedData{}
219                 packedData.Buf = params.Payload
220                 err = e2SubReq.UnPack(packedData)
221                 if err != nil {
222                         xapp.Logger.Error("SubReq: UnPack() failed: %s", err.Error())
223                 }
224                 getErr, subReq := e2SubReq.Get()
225                 if getErr != nil {
226                         xapp.Logger.Error("SubReq: Get() failed: %s", err.Error())
227                 }
228
229
230                 subReq.RequestId.Seq = uint32(subs.GetSubId())
231
232                 err = e2SubReq.Set(subReq)
233                 if err != nil {
234                         xapp.Logger.Error("SubReq: Set() failed: %s", err.Error())
235                         return
236                 }
237                 err, packedData = e2SubReq.Pack(nil)
238                 if err != nil {
239                         xapp.Logger.Error("SubReq: Pack() failed: %s", err.Error())
240                         return
241                 }
242
243                 params.PayloadLen = len(packedData.Buf)
244                 params.Payload = packedData.Buf
245         */
246         //
247         //
248         //
249
250         params.SubId = int(subs.GetSubId())
251         err = c.e2ap.SetSubscriptionRequestSequenceNumber(params.Payload, subs.GetSubId())
252         if err != nil {
253                 xapp.Logger.Error("SubReq: Unable to get Sequence Number from Payload. Dropping this msg. Err: %v, %s", err, params.String())
254                 c.registry.DelSubscription(subs.Seq)
255                 return
256         }
257
258         // Create transatcion record for every subscription request
259         var forwardRespToXapp bool = true
260         var responseReceived bool = false
261         trans, err := c.tracker.TrackTransaction(RmrEndpoint{*srcAddr, *srcPort}, params, responseReceived, forwardRespToXapp)
262         if err != nil {
263                 xapp.Logger.Error("SubReq: %s, Dropping this msg.", err.Error())
264                 c.registry.DelSubscription(subs.Seq)
265                 return
266         }
267
268         err = subs.SetTransaction(trans)
269         if err != nil {
270                 xapp.Logger.Error("SubReq: %s, Dropping this msg.", err.Error())
271                 c.registry.DelSubscription(subs.Seq)
272                 trans.Release()
273                 return
274         }
275
276         c.rmrSend("SubReq to E2T", subs, trans, params.Payload, params.PayloadLen)
277
278         c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.Seq), subReqTime, FirstTry, c.handleSubscriptionRequestTimer)
279         xapp.Logger.Debug("SubReq: Debugging trans table = %v", c.tracker.transactionXappTable)
280         return
281 }
282
283 func (c *Control) handleSubscriptionResponse(params *RMRParams) {
284         xapp.Logger.Info("SubResp from E2T: %s", params.String())
285
286         payloadSeqNum, err := c.e2ap.GetSubscriptionResponseSequenceNumber(params.Payload)
287         if err != nil {
288                 xapp.Logger.Error("SubResp: 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)
289                 return
290         }
291         xapp.Logger.Info("SubResp: Received payloadSeqNum: %v", payloadSeqNum)
292
293         subs := c.registry.GetSubscription(payloadSeqNum)
294         if subs == nil {
295                 xapp.Logger.Error("SubResp: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
296                 return
297         }
298
299         trans := subs.GetTransaction()
300
301         c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum))
302
303         responseReceived := trans.CheckResponseReceived()
304         if responseReceived == true {
305                 // Subscription timer already received
306                 return
307         }
308
309         subs.Confirmed()
310         trans.Release()
311         c.rmrReplyToSender("SubResp to xapp", subs, trans, params.Mtype, params.Payload, params.PayloadLen)
312         xapp.Logger.Info("SubResp: SubId: %v, from address: %s. Deleting trans record", payloadSeqNum, trans.RmrEndpoint)
313         return
314 }
315
316 func (c *Control) handleSubscriptionFailure(params *RMRParams) {
317         xapp.Logger.Info("SubFail from E2T: %s", params.String())
318
319         payloadSeqNum, err := c.e2ap.GetSubscriptionFailureSequenceNumber(params.Payload)
320         if err != nil {
321                 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)
322                 return
323         }
324         xapp.Logger.Info("SubFail: Received payloadSeqNum: %v", payloadSeqNum)
325
326         subs := c.registry.GetSubscription(payloadSeqNum)
327         if subs == nil {
328                 xapp.Logger.Error("SubFail: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
329                 return
330         }
331
332         trans := subs.GetTransaction()
333         if trans == nil {
334                 xapp.Logger.Error("SubFail: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
335                 return
336         }
337
338         c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum))
339
340         responseReceived := trans.CheckResponseReceived()
341         if err != nil {
342                 xapp.Logger.Info("SubFail: Dropping this msg. Err: %v SubId: %v", err, payloadSeqNum)
343                 return
344         }
345
346         if responseReceived == true {
347                 // Subscription timer already received
348                 return
349         }
350         xapp.Logger.Info("SubFail: SubId: %v, from address: %s. Forwarding response to xApp", payloadSeqNum, trans.RmrEndpoint)
351
352         c.rmrReplyToSender("SubFail to xapp", subs, trans, params.Mtype, params.Payload, params.PayloadLen)
353
354         time.Sleep(3 * time.Second)
355
356         xapp.Logger.Info("SubFail: Deleting trans record. SubId: %v, Xid: %s", params.SubId, params.Xid)
357         trans.Release()
358         if !c.registry.DelSubscription(payloadSeqNum) {
359                 xapp.Logger.Error("SubFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid)
360         }
361         return
362 }
363
364 func (c *Control) handleSubscriptionRequestTimer(strId string, nbrId int, tryCount uint64) {
365         xapp.Logger.Info("SubReq timeout: subId: %v,  tryCount: %v", nbrId, tryCount)
366
367         subs := c.registry.GetSubscription(uint16(nbrId))
368         if subs == nil {
369                 xapp.Logger.Error("SubReq timeout: Unknown payloadSeqNum. Dropping this msg. SubId: %v", nbrId)
370                 return
371         }
372
373         trans := subs.GetTransaction()
374         if trans == nil {
375                 xapp.Logger.Error("SubReq timeout: Unknown trans. Dropping this msg. SubId: %v", subs.GetSubId())
376                 return
377         }
378
379         responseReceived := trans.CheckResponseReceived()
380
381         if responseReceived == true {
382                 // Subscription Response or Failure already received
383                 return
384         }
385
386         if tryCount < maxSubReqTryCount {
387                 xapp.Logger.Info("SubReq timeout: Resending SubReq to E2T: Mtype: %v, SubId: %v, Xid %s, Meid %v", trans.OrigParams.Mtype, subs.GetSubId(), trans.GetXid(), subs.GetMeid())
388
389                 trans.RetryTransaction()
390
391                 c.rmrSend("SubReq(SubReq timer) to E2T", subs, trans, trans.OrigParams.Payload, trans.OrigParams.PayloadLen)
392
393                 tryCount++
394                 c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionRequestTimer)
395                 return
396         }
397
398         var subDelReqPayload []byte
399         subDelReqPayload, err := c.e2ap.PackSubscriptionDeleteRequest(trans.OrigParams.Payload, subs.GetSubId())
400         if err != nil {
401                 xapp.Logger.Error("SubReq timeout: Packing SubDelReq failed. Err: %v", err)
402                 return
403         }
404
405         // Cancel failed subscription
406         params := &RMRParams{&xapp.RMRParams{}}
407         params.Mtype = 12020 // RIC SUBSCRIPTION DELETE
408         params.SubId = int(subs.GetSubId())
409         params.Xid = trans.GetXid()
410         params.Meid = subs.GetMeid()
411         params.Src = trans.OrigParams.Src
412         params.PayloadLen = len(subDelReqPayload)
413         params.Payload = subDelReqPayload
414         params.Mbuf = nil
415
416         // Delete CREATE transaction
417         trans.Release()
418
419         // Create DELETE transaction (internal and no messages toward xapp)
420         var forwardRespToXapp bool = false
421         var respReceived bool = false
422         deltrans, err := c.tracker.TrackTransaction(trans.RmrEndpoint, params, respReceived, forwardRespToXapp)
423         if err != nil {
424                 xapp.Logger.Error("SubReq timeout: %s, Dropping this msg.", err.Error())
425                 return
426         }
427
428         err = subs.SetTransaction(deltrans)
429         if err != nil {
430                 xapp.Logger.Error("SubReq timeout: %s, Dropping this msg.", err.Error())
431                 deltrans.Release()
432                 return
433         }
434
435         c.rmrSend("SubDelReq(SubReq timer) to E2T", subs, deltrans, deltrans.OrigParams.Payload, deltrans.OrigParams.PayloadLen)
436
437         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
438         return
439 }
440
441 func (c *Control) handleSubscriptionDeleteRequest(params *RMRParams) {
442         xapp.Logger.Info("SubDelReq from xapp: %s", params.String())
443
444         srcAddr, srcPort, err := c.rtmgrClient.SplitSource(params.Src)
445         if err != nil {
446                 xapp.Logger.Error("SubDelReq: Failed to update routing-manager. Dropping this msg. Err: %s, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
447                 return
448         }
449
450         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteRequestSequenceNumber(params.Payload)
451         if err != nil {
452                 xapp.Logger.Error("SubDelReq: 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)
453                 return
454         }
455         xapp.Logger.Info("SubDelReq: Received payloadSeqNum: %v", payloadSeqNum)
456
457         subs := c.registry.GetSubscription(payloadSeqNum)
458         if subs == nil {
459                 xapp.Logger.Error("SubDelReq: Not valid sequence number. Dropping this msg. SubId: %v, Xid: %s", params.SubId, params.Xid)
460                 return
461         }
462
463         var forwardRespToXapp bool = true
464         var respReceived bool = false
465         trans, err := c.tracker.TrackTransaction(RmrEndpoint{*srcAddr, *srcPort}, params, respReceived, forwardRespToXapp)
466         if err != nil {
467                 xapp.Logger.Error("SubDelReq: %s, Dropping this msg.", err.Error())
468                 return
469         }
470
471         err = subs.SetTransaction(trans)
472         if err != nil {
473                 xapp.Logger.Error("SubDelReq: %s, Dropping this msg.", err.Error())
474                 trans.Release()
475                 return
476         }
477
478         subs.UnConfirmed()
479
480         c.rmrSend("SubDelReq to E2T", subs, trans, trans.OrigParams.Payload, trans.OrigParams.PayloadLen)
481
482         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
483         return
484 }
485
486 func (c *Control) handleSubscriptionDeleteResponse(params *RMRParams) (err error) {
487         xapp.Logger.Info("SubDelResp from E2T:%s", params.String())
488
489         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteResponseSequenceNumber(params.Payload)
490         if err != nil {
491                 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)
492                 return
493         }
494         xapp.Logger.Info("SubDelResp: Received payloadSeqNum: %v", payloadSeqNum)
495
496         subs := c.registry.GetSubscription(payloadSeqNum)
497         if subs == nil {
498                 xapp.Logger.Error("SubDelResp: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
499                 return
500         }
501
502         trans := subs.GetTransaction()
503         if trans == nil {
504                 xapp.Logger.Error("SubDelResp: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", subs.GetSubId(), params.SubId)
505                 return
506         }
507
508         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
509
510         responseReceived := trans.CheckResponseReceived()
511         if responseReceived == true {
512                 // Subscription Delete timer already received
513                 return
514         }
515
516         trans.Release()
517
518         if trans.ForwardRespToXapp == true {
519                 c.rmrReplyToSender("SubDelResp to xapp", subs, trans, params.Mtype, params.Payload, params.PayloadLen)
520                 time.Sleep(3 * time.Second)
521         }
522
523         xapp.Logger.Info("SubDelResp: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
524         if !c.registry.DelSubscription(subs.GetSubId()) {
525                 xapp.Logger.Error("SubDelResp: Failed to release sequency number. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
526                 return
527         }
528         return
529 }
530
531 func (c *Control) handleSubscriptionDeleteFailure(params *RMRParams) {
532         xapp.Logger.Info("SubDelFail from E2T:%s", params.String())
533
534         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteFailureSequenceNumber(params.Payload)
535         if err != nil {
536                 xapp.Logger.Error("SubDelFail: Unable to get Sequence Number from Payload. Dropping this msg. Err: %v, %s", err, params.String())
537                 return
538         }
539         xapp.Logger.Info("SubDelFail: Received payloadSeqNum: %v", payloadSeqNum)
540
541         subs := c.registry.GetSubscription(payloadSeqNum)
542         if subs == nil {
543                 xapp.Logger.Error("SubDelFail: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
544                 return
545         }
546
547         trans := subs.GetTransaction()
548         if trans == nil {
549                 xapp.Logger.Error("SubDelFail: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", subs.GetSubId(), params.SubId)
550                 return
551         }
552
553         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
554
555         responseReceived := trans.CheckResponseReceived()
556         if responseReceived == true {
557                 // Subscription Delete timer already received
558                 return
559         }
560         if trans.ForwardRespToXapp == true {
561                 var subDelRespPayload []byte
562                 subDelRespPayload, err = c.e2ap.PackSubscriptionDeleteResponse(trans.OrigParams.Payload, subs.GetSubId())
563                 if err != nil {
564                         xapp.Logger.Error("SubDelFail:Packing SubDelResp failed. Err: %v", err)
565                         return
566                 }
567
568                 // RIC SUBSCRIPTION DELETE RESPONSE
569                 c.rmrReplyToSender("SubDelFail to xapp", subs, trans, 12021, subDelRespPayload, len(subDelRespPayload))
570                 time.Sleep(3 * time.Second)
571         }
572
573         xapp.Logger.Info("SubDelFail: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
574         trans.Release()
575         if !c.registry.DelSubscription(subs.GetSubId()) {
576                 xapp.Logger.Error("SubDelFail: Failed to release sequency number. Err: %v, SubId: %v, Xid: %s", err, subs.GetSubId(), trans.GetXid())
577                 return
578         }
579         return
580 }
581
582 func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int, tryCount uint64) {
583         xapp.Logger.Info("SubDelReq timeout: subId: %v, tryCount: %v", nbrId, tryCount)
584
585         subs := c.registry.GetSubscription(uint16(nbrId))
586         if subs == nil {
587                 xapp.Logger.Error("SubDelReq timeout: Unknown payloadSeqNum. Dropping this msg. SubId: %v", nbrId)
588                 return
589         }
590
591         trans := subs.GetTransaction()
592         if trans == nil {
593                 xapp.Logger.Error("SubDelReq timeout: Unknown trans. Dropping this msg. SubId: %v", subs.GetSubId())
594                 return
595         }
596
597         responseReceived := trans.CheckResponseReceived()
598         if responseReceived == true {
599                 // Subscription Delete Response or Failure already received
600                 return
601         }
602
603         if tryCount < maxSubDelReqTryCount {
604                 xapp.Logger.Info("SubDelReq timeout: Resending SubDelReq to E2T: Mtype: %v, SubId: %v, Xid %s, Meid %v", trans.OrigParams.Mtype, subs.GetSubId(), trans.GetXid(), subs.GetMeid())
605                 // Set possible to handle new response for the subId
606
607                 trans.RetryTransaction()
608
609                 c.rmrSend("SubDelReq(SubDelReq timer) to E2T", subs, trans, trans.OrigParams.Payload, trans.OrigParams.PayloadLen)
610
611                 tryCount++
612                 c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionDeleteRequestTimer)
613                 return
614         }
615
616         if trans.ForwardRespToXapp == true {
617                 var subDelRespPayload []byte
618                 subDelRespPayload, err := c.e2ap.PackSubscriptionDeleteResponse(trans.OrigParams.Payload, subs.GetSubId())
619                 if err != nil {
620                         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.OrigParams.Payload)
621                         return
622                 }
623
624                 // RIC SUBSCRIPTION DELETE RESPONSE
625                 c.rmrReplyToSender("SubDelResp(SubDelReq timer) to xapp", subs, trans, 12021, subDelRespPayload, len(subDelRespPayload))
626
627                 time.Sleep(3 * time.Second)
628
629         }
630
631         xapp.Logger.Info("SubDelReq timeout: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
632         trans.Release()
633         if !c.registry.DelSubscription(subs.GetSubId()) {
634                 xapp.Logger.Error("SubDelReq timeout: Failed to release sequency number. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
635         }
636         return
637 }