RICPLT-2984 SubDelFail 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: SubReq to E2T", subs, trans, trans.Payload, trans.PayloadLen)
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: 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                 //Optimize and store packed message to be sent.
384                 trans.Payload = packedData.Buf
385                 trans.PayloadLen = len(packedData.Buf)
386                 c.rmrReplyToSender("SubFail: SubFail to xapp", subs, trans, 12012, trans.Payload, trans.PayloadLen)
387                 time.Sleep(3 * time.Second)
388         } else {
389                 //TODO error handling improvement
390                 xapp.Logger.Error("SubFail: %s for trans %s (continuing cleaning)", err.Error(), trans)
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 timeout: SubReq 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         // Release 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("SubReq timer: SubDelReq to E2T", subs, deltrans, deltrans.Payload, deltrans.PayloadLen)
474         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
475         return
476 }
477
478 func (c *Control) handleSubscriptionDeleteRequest(params *RMRParams) {
479         xapp.Logger.Info("SubDelReq from xapp: %s", params.String())
480
481         //
482         //
483         //
484         trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src),
485                 params.Mtype,
486                 params.Xid,
487                 params.Meid,
488                 false,
489                 true)
490
491         if err != nil {
492                 xapp.Logger.Error("SubDelReq: %s, Dropping this msg. %s", err.Error(), params.String())
493                 return
494         }
495
496         //
497         //
498         //
499         trans.SubDelReqMsg, err = c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
500         if err != nil {
501                 xapp.Logger.Error("SubDelReq: %s Dropping this msg. %s", err.Error(), trans)
502                 trans.Release()
503                 return
504         }
505
506         //
507         //
508         //
509         subs := c.registry.GetSubscription(uint16(trans.SubDelReqMsg.RequestId.Seq))
510         if subs == nil && params.SubId > 0 {
511                 subs = c.registry.GetSubscription(uint16(params.SubId))
512         }
513
514         if subs == nil {
515                 xapp.Logger.Error("SubDelReq: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", trans.SubDelReqMsg.RequestId.Seq, params.SubId, trans)
516                 trans.Release()
517                 return
518         }
519         xapp.Logger.Info("SubDelReq: subscription found payloadSeqNum: %d, SubId: %d. %s", trans.SubDelReqMsg.RequestId.Seq, params.SubId, trans)
520
521         err = subs.SetTransaction(trans)
522         if err != nil {
523                 xapp.Logger.Error("SubDelReq: %s, Dropping this msg. %s", err.Error(), trans)
524                 trans.Release()
525                 return
526         }
527
528         //
529         // TODO: subscription delete is in fact owned by subscription and not transaction.
530         //       Transaction is toward xapp while Subscription is toward ran.
531         //       In merge several xapps may wake transactions, while only one subscription
532         //       toward ran occurs -> subscription owns subscription creation toward ran
533         //
534         //       This is intermediate solution while improving message handling
535         //
536         packedData, err := c.e2ap.PackSubscriptionDeleteRequest(trans.SubDelReqMsg)
537         if err != nil {
538                 xapp.Logger.Error("SubDelReq: %s for trans %s", err.Error(), trans)
539                 trans.Release()
540                 return
541         }
542
543         //Optimize and store packed message to be sent (for retransmission). Again owned by subscription?
544         trans.Payload = packedData.Buf
545         trans.PayloadLen = len(packedData.Buf)
546
547         subs.UnConfirmed()
548
549         c.rmrSend("SubDelReq: SubDelReq to E2T", subs, trans, trans.Payload, trans.PayloadLen)
550
551         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
552         return
553 }
554
555 func (c *Control) handleSubscriptionDeleteResponse(params *RMRParams) (err error) {
556         xapp.Logger.Info("SubDelResp from E2T:%s", params.String())
557
558         //
559         //
560         //
561         SubDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload)
562         if err != nil {
563                 xapp.Logger.Error("SubDelResp: %s Dropping this msg. %s", err.Error(), params.String())
564                 return
565         }
566
567         //
568         //
569         //
570         subs := c.registry.GetSubscription(uint16(SubDelRespMsg.RequestId.Seq))
571         if subs == nil && params.SubId > 0 {
572                 subs = c.registry.GetSubscription(uint16(params.SubId))
573         }
574
575         if subs == nil {
576                 xapp.Logger.Error("SubDelResp: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", SubDelRespMsg.RequestId.Seq, params.SubId, params.String())
577                 return
578         }
579         xapp.Logger.Info("SubDelResp: subscription found payloadSeqNum: %d, SubId: %d", SubDelRespMsg.RequestId.Seq, subs.GetSubId())
580
581         //
582         //
583         //
584         trans := subs.GetTransaction()
585         if trans == nil {
586                 xapp.Logger.Error("SubDelResp: Unknown trans. Dropping this msg. SubId: %d", subs.GetSubId())
587                 return
588         }
589
590         trans.SubDelRespMsg = SubDelRespMsg
591
592         //
593         //
594         //
595         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
596
597         responseReceived := trans.CheckResponseReceived()
598         if responseReceived == true {
599                 // Subscription Delete timer already received
600                 return
601         }
602
603         c.sendSubscriptionDeleteResponse("SubDelResp", trans, subs)
604         return
605 }
606
607 func (c *Control) handleSubscriptionDeleteFailure(params *RMRParams) {
608         xapp.Logger.Info("SubDelFail from E2T:%s", params.String())
609
610         //
611         //
612         //
613         SubDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload)
614         if err != nil {
615                 xapp.Logger.Error("SubDelFail: %s Dropping this msg. %s", err.Error(), params.String())
616                 return
617         }
618
619         //
620         //
621         //
622         subs := c.registry.GetSubscription(uint16(SubDelFailMsg.RequestId.Seq))
623         if subs == nil && params.SubId > 0 {
624                 subs = c.registry.GetSubscription(uint16(params.SubId))
625         }
626
627         if subs == nil {
628                 xapp.Logger.Error("SubDelFail: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", SubDelFailMsg.RequestId.Seq, params.SubId, params.String())
629                 return
630         }
631         xapp.Logger.Info("SubDelFail: subscription found payloadSeqNum: %d, SubId: %d", SubDelFailMsg.RequestId.Seq, subs.GetSubId())
632
633         //
634         //
635         //
636         trans := subs.GetTransaction()
637         if trans == nil {
638                 xapp.Logger.Error("SubDelFail: Unknown trans. Dropping this msg. SubId: %d", subs.GetSubId())
639                 return
640         }
641         trans.SubDelFailMsg = SubDelFailMsg
642
643         //
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
654         c.sendSubscriptionDeleteResponse("SubDelFail", trans, subs)
655         return
656 }
657
658 func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int, tryCount uint64) {
659         xapp.Logger.Info("SubDelReq timeout: subId: %v, tryCount: %v", nbrId, tryCount)
660
661         subs := c.registry.GetSubscription(uint16(nbrId))
662         if subs == nil {
663                 xapp.Logger.Error("SubDelReq timeout: Unknown payloadSeqNum. Dropping this msg. SubId: %v", nbrId)
664                 return
665         }
666
667         trans := subs.GetTransaction()
668         if trans == nil {
669                 xapp.Logger.Error("SubDelReq timeout: Unknown trans. Dropping this msg. SubId: %v", subs.GetSubId())
670                 return
671         }
672
673         responseReceived := trans.CheckResponseReceived()
674         if responseReceived == true {
675                 // Subscription Delete Response or Failure already received
676                 return
677         }
678
679         if tryCount < maxSubDelReqTryCount {
680                 // Set possible to handle new response for the subId
681                 trans.RetryTransaction()
682                 c.rmrSend("SubDelReq timeout: SubDelReq to E2T", subs, trans, trans.Payload, trans.PayloadLen)
683                 tryCount++
684                 c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionDeleteRequestTimer)
685                 return
686         }
687
688         c.sendSubscriptionDeleteResponse("SubDelReq(timer)", trans, subs)
689         return
690 }
691
692 func (c *Control) sendSubscriptionDeleteResponse(desc string, trans *Transaction, subs *Subscription) {
693
694         if trans.ForwardRespToXapp == true {
695                 //Always generate SubDelResp
696                 trans.SubDelRespMsg = &e2ap.E2APSubscriptionDeleteResponse{}
697                 trans.SubDelRespMsg.RequestId.Id = trans.SubDelReqMsg.RequestId.Id
698                 trans.SubDelRespMsg.RequestId.Seq = uint32(subs.GetSubId())
699                 trans.SubDelRespMsg.FunctionId = trans.SubDelReqMsg.FunctionId
700
701                 packedData, err := c.e2ap.PackSubscriptionDeleteResponse(trans.SubDelRespMsg)
702                 if err == nil {
703                         trans.Payload = packedData.Buf
704                         trans.PayloadLen = len(packedData.Buf)
705                         c.rmrReplyToSender(desc+": SubDelResp to xapp", subs, trans, 12021, trans.Payload, trans.PayloadLen)
706                         time.Sleep(3 * time.Second)
707                 } else {
708                         //TODO error handling improvement
709                         xapp.Logger.Error("%s: %s for trans %s (continuing cleaning)", desc, err.Error(), trans)
710                 }
711         }
712
713         trans.Release()
714         subs.Release()
715 }