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