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