a1b23288af3a91f9e2d2a6f9ca436a991131f67a
[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         params.SubId = int(payloadSeqNum)
291         params.Xid = transaction.OrigParams.Xid
292
293         xapp.Logger.Info("SubFail: Forwarding SubFail to xApp: Mtype: %v, SubId: %v, Xid: %v, Meid: %v", params.Mtype, params.SubId, params.Xid, params.Meid)
294         err = c.rmrReplyToSender(params)
295         if err != nil {
296                 xapp.Logger.Error("SubFail: Failed to send response to xApp. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
297         }
298
299         time.Sleep(3 * time.Second)
300
301         xapp.Logger.Info("SubFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
302         transaction.Release()
303         if !c.registry.DelSubscription(payloadSeqNum) {
304                 xapp.Logger.Error("SubFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid)
305         }
306         return
307 }
308
309 func (c *Control) handleSubscriptionRequestTimer(strId string, nbrId int, tryCount uint64) {
310         subId := uint16(nbrId)
311         xapp.Logger.Info("handleSubTimer: SubReq timer expired. subId: %v,  tryCount: %v", subId, tryCount)
312
313         subs := c.registry.GetSubscription(subId)
314         if subs == nil {
315                 xapp.Logger.Error("SubFail: Unknown payloadSeqNum. Dropping this msg. SubId: %v", subId)
316                 return
317         }
318
319         transaction := subs.GetTransaction()
320         if transaction == nil {
321                 xapp.Logger.Error("SubFail: Unknown transaction. Dropping this msg. SubId: %v", subId)
322                 return
323         }
324
325         responseReceived := transaction.CheckResponseReceived()
326
327         if responseReceived == true {
328                 // Subscription Response or Failure already received
329                 return
330         }
331
332         if tryCount < maxSubReqTryCount {
333                 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)
334
335                 transaction.RetryTransaction()
336
337                 err := c.rmrSend(transaction.OrigParams)
338                 if err != nil {
339                         xapp.Logger.Error("handleSubTimer: Failed to send request to E2T %v, SubId: %v, Xid: %s", err, transaction.OrigParams.SubId, transaction.OrigParams.Xid)
340                 }
341
342                 tryCount++
343                 c.timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, tryCount, c.handleSubscriptionRequestTimer)
344                 return
345         }
346
347         var subDelReqPayload []byte
348         subDelReqPayload, err := c.e2ap.PackSubscriptionDeleteRequest(transaction.OrigParams.Payload, subId)
349         if err != nil {
350                 xapp.Logger.Error("handleSubTimer: Packing SubDelReq failed. Err: %v", err)
351                 return
352         }
353
354         // Cancel failed subscription
355         var params xapp.RMRParams
356         params.Mtype = 12020 // RIC SUBSCRIPTION DELETE
357         params.SubId = int(subId)
358         params.Xid = transaction.OrigParams.Xid
359         params.Meid = transaction.OrigParams.Meid
360         params.Src = transaction.OrigParams.Src
361         params.PayloadLen = len(subDelReqPayload)
362         params.Payload = subDelReqPayload
363         params.Mbuf = nil
364
365         // Delete CREATE transaction
366         transaction.Release()
367
368         // Create DELETE transaction
369         _, err = c.trackDeleteTransaction(subs, &params, subId, false)
370         if err != nil {
371                 xapp.Logger.Error("handleSubTimer: %s, Dropping this msg.", err.Error())
372                 return
373         }
374
375         xapp.Logger.Info("handleSubTimer: Sending SubDelReq to E2T: Mtype: %v, SubId: %v, Meid: %v", params.Mtype, params.SubId, params.Meid)
376         c.rmrSend(&params)
377         if err != nil {
378                 xapp.Logger.Error("handleSubTimer: Failed to send request to E2T %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid)
379         }
380         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subId), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
381         return
382 }
383
384 func (act Action) String() string {
385         actions := [...]string{
386                 "CREATE",
387                 "MERGE",
388                 "NONE",
389                 "DELETE",
390         }
391
392         if act < CREATE || act > DELETE {
393                 return "Unknown"
394         }
395         return actions[act]
396 }
397
398 func (act Action) valid() bool {
399         switch act {
400         case CREATE, MERGE, DELETE:
401                 return true
402         default:
403                 return false
404         }
405 }
406
407 func (c *Control) handleSubscriptionDeleteRequest(params *xapp.RMRParams) {
408         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)
409         xapp.Rmr.Free(params.Mbuf)
410         params.Mbuf = nil
411
412         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteRequestSequenceNumber(params.Payload)
413         if err != nil {
414                 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)
415                 return
416         }
417         xapp.Logger.Info("SubDelReq: Received payloadSeqNum: %v", payloadSeqNum)
418
419         subs := c.registry.GetSubscription(payloadSeqNum)
420         if subs != nil {
421                 var forwardRespToXapp bool = true
422                 _, err = c.trackDeleteTransaction(subs, params, payloadSeqNum, forwardRespToXapp)
423                 if err != nil {
424                         xapp.Logger.Error("SubDelReq: %s, Dropping this msg.", err.Error())
425                         return
426                 }
427                 subs.UnConfirmed()
428         } else {
429                 xapp.Logger.Error("SubDelReq: Not valid sequence number. Dropping this msg. SubId: %v, Xid: %s", params.SubId, params.Xid)
430                 return
431         }
432
433         xapp.Logger.Info("SubDelReq: Forwarding Request to E2T. Mtype: %v, SubId: %v, Xid: %s, Meid: %v", params.Mtype, params.SubId, params.Xid, params.Meid)
434         c.rmrSend(params)
435         if err != nil {
436                 xapp.Logger.Error("SubDelReq: Failed to send request to E2T. Err %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
437         }
438         c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
439         return
440 }
441
442 func (c *Control) trackDeleteTransaction(subs *Subscription, params *xapp.RMRParams, payloadSeqNum uint16, forwardRespToXapp bool) (transaction *Transaction, err error) {
443         srcAddr, srcPort, err := c.rtmgrClient.SplitSource(params.Src)
444         if err != nil {
445                 xapp.Logger.Error("Failed to split source address. Err: %s, SubId: %v, Xid: %s", err, payloadSeqNum, params.Xid)
446         }
447         var respReceived bool = false
448         transaction, err = c.tracker.TrackTransaction(subs, RmrEndpoint{*srcAddr, *srcPort}, params, respReceived, forwardRespToXapp)
449         return
450 }
451
452 func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
453         xapp.Logger.Info("SubDelResp received from Src: %s, Mtype: %v, SubId: %v, Meid: %v", params.Src, params.Mtype, params.SubId, params.Meid)
454         xapp.Rmr.Free(params.Mbuf)
455         params.Mbuf = nil
456
457         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteResponseSequenceNumber(params.Payload)
458         if err != nil {
459                 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)
460                 return
461         }
462         xapp.Logger.Info("SubDelResp: Received payloadSeqNum: %v", payloadSeqNum)
463
464         subs := c.registry.GetSubscription(payloadSeqNum)
465         if subs == nil {
466                 xapp.Logger.Error("SubDelResp: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
467                 return
468         }
469
470         transaction := subs.GetTransaction()
471         if transaction == nil {
472                 xapp.Logger.Error("SubDelResp: Unknown transaction. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
473                 return
474         }
475
476         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum))
477
478         responseReceived := transaction.CheckResponseReceived()
479         if responseReceived == true {
480                 // Subscription Delete timer already received
481                 return
482         }
483
484         transaction.Release()
485
486         xapp.Logger.Info("SubDelResp: SubId: %v, from address: %s. Forwarding response to xApp", payloadSeqNum, transaction.RmrEndpoint)
487         if transaction.ForwardRespToXapp == true {
488                 params.SubId = int(payloadSeqNum)
489                 params.Xid = transaction.OrigParams.Xid
490                 xapp.Logger.Info("Forwarding SubDelResp to xApp: Mtype: %v, SubId: %v, Xid: %v, Meid: %v", params.Mtype, params.SubId, params.Xid, params.Meid)
491                 err = c.rmrReplyToSender(params)
492                 if err != nil {
493                         xapp.Logger.Error("SubDelResp: Failed to send response to xApp. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
494                 }
495
496                 time.Sleep(3 * time.Second)
497         }
498
499         xapp.Logger.Info("SubDelResp: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
500         if !c.registry.DelSubscription(payloadSeqNum) {
501                 xapp.Logger.Error("SubDelResp: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid)
502                 return
503         }
504         return
505 }
506
507 func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) {
508         xapp.Logger.Info("SubDelFail received from Src: %s, Mtype: %v, SubId: %v, Meid: %v", params.Src, params.Mtype, params.SubId, params.Meid)
509         xapp.Rmr.Free(params.Mbuf)
510         params.Mbuf = nil
511
512         payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteFailureSequenceNumber(params.Payload)
513         if err != nil {
514                 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)
515                 return
516         }
517         xapp.Logger.Info("SubDelFail: Received payloadSeqNum: %v", payloadSeqNum)
518
519         subs := c.registry.GetSubscription(payloadSeqNum)
520         if subs == nil {
521                 xapp.Logger.Error("SubDelFail: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
522                 return
523         }
524
525         transaction := subs.GetTransaction()
526         if transaction == nil {
527                 xapp.Logger.Error("SubDelFail: Unknown transaction. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
528                 return
529         }
530
531         c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum))
532
533         responseReceived := transaction.CheckResponseReceived()
534         if responseReceived == true {
535                 // Subscription Delete timer already received
536                 return
537         }
538         xapp.Logger.Info("SubDelFail: SubId: %v, from address: %s. Forwarding response to xApp", payloadSeqNum, transaction.RmrEndpoint)
539
540         if transaction.ForwardRespToXapp == true {
541                 var subDelRespPayload []byte
542                 subDelRespPayload, err = c.e2ap.PackSubscriptionDeleteResponse(transaction.OrigParams.Payload, payloadSeqNum)
543                 if err != nil {
544                         xapp.Logger.Error("SubDelFail:Packing SubDelResp failed. Err: %v", err)
545                         return
546                 }
547
548                 params.Mtype = 12021 // RIC SUBSCRIPTION DELETE RESPONSE
549                 params.SubId = int(payloadSeqNum)
550                 params.Xid = transaction.OrigParams.Xid
551                 params.Meid = transaction.OrigParams.Meid
552                 params.Src = transaction.OrigParams.Src
553                 params.PayloadLen = len(subDelRespPayload)
554                 params.Payload = subDelRespPayload
555                 params.Mbuf = nil
556                 xapp.Logger.Info("SubDelFail: Forwarding SubDelResp to xApp: Mtype: %v, SubId: %v, Xid: %v, Meid: %v", params.Mtype, params.SubId, params.Xid, params.Meid)
557                 err = c.rmrReplyToSender(params)
558                 if err != nil {
559                         xapp.Logger.Error("SubDelFail: Failed to send SubDelResp to xApp. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
560                 }
561
562                 time.Sleep(3 * time.Second)
563         }
564
565         xapp.Logger.Info("SubDelFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
566         transaction.Release()
567         if !c.registry.DelSubscription(payloadSeqNum) {
568                 xapp.Logger.Error("SubDelFail: Failed to release sequency number. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
569                 return
570         }
571         return
572 }
573
574 func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int, tryCount uint64) {
575         subId := uint16(nbrId)
576         xapp.Logger.Info("handleSubDelTimer: SubDelReq timer expired. subId: %v, tryCount: %v", subId, tryCount)
577
578         subs := c.registry.GetSubscription(subId)
579         if subs == nil {
580                 xapp.Logger.Error("handleSubDelTimer: Unknown payloadSeqNum. Dropping this msg. SubId: %v", subId)
581                 return
582         }
583
584         transaction := subs.GetTransaction()
585         if transaction == nil {
586                 xapp.Logger.Error("handleSubDelTimer: Unknown transaction. Dropping this msg. SubId: %v", subId)
587                 return
588         }
589
590         responseReceived := transaction.CheckResponseReceived()
591         if responseReceived == true {
592                 // Subscription Delete Response or Failure already received
593                 return
594         }
595
596         if tryCount < maxSubDelReqTryCount {
597                 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)
598                 // Set possible to handle new response for the subId
599
600                 transaction.RetryTransaction()
601
602                 err := c.rmrSend(transaction.OrigParams)
603                 if err != nil {
604                         xapp.Logger.Error("handleSubDelTimer: Failed to send request to E2T %v, SubId: %v, Xid: %s", err, transaction.OrigParams.SubId, transaction.OrigParams.Xid)
605                 }
606
607                 tryCount++
608                 c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subId), subReqTime, tryCount, c.handleSubscriptionDeleteRequestTimer)
609                 return
610         }
611
612         var params xapp.RMRParams
613         if transaction.ForwardRespToXapp == true {
614                 var subDelRespPayload []byte
615                 subDelRespPayload, err := c.e2ap.PackSubscriptionDeleteResponse(transaction.OrigParams.Payload, subId)
616                 if err != nil {
617                         xapp.Logger.Error("handleSubDelTimer: Unable to pack payload. Dropping this this msg. Err: %v, SubId: %v, Xid: %s, Payload %x", err, subId, transaction.OrigParams.Xid, transaction.OrigParams.Payload)
618                         return
619                 }
620
621                 params.Mtype = 12021 // RIC SUBSCRIPTION DELETE RESPONSE
622                 params.SubId = int(subId)
623                 params.Meid = transaction.OrigParams.Meid
624                 params.Xid = transaction.OrigParams.Xid
625                 params.Src = transaction.OrigParams.Src
626                 params.PayloadLen = len(subDelRespPayload)
627                 params.Payload = subDelRespPayload
628                 params.Mbuf = nil
629
630                 xapp.Logger.Info("handleSubDelTimer: Sending SubDelResp to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v", params.Mtype, params.SubId, params.Xid, params.Meid)
631                 err = c.rmrReplyToSender(&params)
632                 if err != nil {
633                         xapp.Logger.Error("handleSubDelTimer: Failed to send response to xApp: Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
634                 }
635
636                 time.Sleep(3 * time.Second)
637         }
638
639         xapp.Logger.Info("handleSubDelTimer: Deleting transaction record. SubId: %v, Xid: %s", subId, params.Xid)
640         transaction.Release()
641         if !c.registry.DelSubscription(subId) {
642                 xapp.Logger.Error("handleSubDelTimer: Failed to release sequency number. SubId: %v, Xid: %s", subId, params.Xid)
643         }
644         return
645 }