+ deltrans.PayloadLen = len(packedData.Buf)
+ deltrans.Payload = packedData.Buf
+
+ err = subs.SetTransaction(deltrans)
+ if err != nil {
+ xapp.Logger.Error("SubReq timeout: %s, Dropping this msg.", err.Error())
+ //TODO improve error handling. Important at least in merge
+ deltrans.Release()
+ return
+ }
+
+ c.rmrSend("SubDelReq(SubReq timer) to E2T", subs, deltrans, deltrans.Payload, deltrans.PayloadLen)
+
+ c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
+ return
+}
+
+func (c *Control) handleSubscriptionDeleteRequest(params *RMRParams) {
+ var subs *Subscription
+
+ xapp.Logger.Info("SubDelReq from xapp: %s", params.String())
+
+ trans, err := c.tracker.TrackTransaction(NewRmrEndpoint(params.Src),
+ params.Mtype,
+ params.Xid,
+ params.Meid,
+ false,
+ true)
+
+ if err != nil {
+ xapp.Logger.Error("SubDelReq: %s, Dropping this msg. %s", err.Error(), params.String())
+ return
+ }
+
+ //
+ //
+ //
+ trans.SubDelReqMsg, err = c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
+ if err != nil {
+ xapp.Logger.Error("SubDelReq: %s Dropping this msg. %s", err.Error(), trans)
+ trans.Release()
+ return
+ }
+
+ subs = c.registry.GetSubscription(uint16(trans.SubDelReqMsg.RequestId.Seq))
+ if subs == nil && params.SubId > 0 {
+ subs = c.registry.GetSubscription(uint16(params.SubId))
+ }
+
+ if subs == nil {
+ xapp.Logger.Error("SubDelReq: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", trans.SubDelReqMsg.RequestId.Seq, params.SubId, trans)
+ trans.Release()
+ return
+ }
+ xapp.Logger.Info("SubDelReq: subscription found payloadSeqNum: %d, SubId: %d. %s", trans.SubDelReqMsg.RequestId.Seq, params.SubId, trans)
+
+ err = subs.SetTransaction(trans)
+ if err != nil {
+ xapp.Logger.Error("SubDelReq: %s, Dropping this msg. %s", err.Error(), trans)
+ trans.Release()
+ return
+ }
+
+ //
+ // TODO: subscription delete is in fact owned by subscription and not transaction.
+ // Transaction is toward xapp while Subscription is toward ran.
+ // In merge several xapps may wake transactions, while only one subscription
+ // toward ran occurs -> subscription owns subscription creation toward ran
+ //
+ // This is intermediate solution while improving message handling
+ //
+ packedData, err := c.e2ap.PackSubscriptionDeleteRequest(trans.SubDelReqMsg)
+ if err != nil {
+ xapp.Logger.Error("SubDelReq: %s for trans %s", err.Error(), trans)
+ trans.Release()
+ return
+ }
+
+ //Optimize and store packed message to be sent (for retransmission). Again owned by subscription?
+ trans.Payload = packedData.Buf
+ trans.PayloadLen = len(packedData.Buf)
+
+ subs.UnConfirmed()
+
+ c.rmrSend("SubDelReq to E2T", subs, trans, trans.Payload, trans.PayloadLen)
+
+ c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subDelReqTime, FirstTry, c.handleSubscriptionDeleteRequestTimer)
+ return
+}
+
+func (c *Control) handleSubscriptionDeleteResponse(params *RMRParams) (err error) {
+ xapp.Logger.Info("SubDelResp from E2T:%s", params.String())
+
+ payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteResponseSequenceNumber(params.Payload)
+ if err != nil {
+ 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)
+ return
+ }
+ xapp.Logger.Info("SubDelResp: Received payloadSeqNum: %v", payloadSeqNum)
+
+ subs := c.registry.GetSubscription(payloadSeqNum)
+ if subs == nil {
+ xapp.Logger.Error("SubDelResp: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
+ return
+ }
+
+ trans := subs.GetTransaction()
+ if trans == nil {
+ xapp.Logger.Error("SubDelResp: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", subs.GetSubId(), params.SubId)
+ return
+ }
+
+ c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
+
+ responseReceived := trans.CheckResponseReceived()
+ if responseReceived == true {
+ // Subscription Delete timer already received
+ return
+ }
+
+ trans.Release()
+
+ if trans.ForwardRespToXapp == true {
+ c.rmrReplyToSender("SubDelResp to xapp", subs, trans, params.Mtype, params.Payload, params.PayloadLen)
+ time.Sleep(3 * time.Second)
+ }
+
+ xapp.Logger.Info("SubDelResp: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
+ if !c.registry.DelSubscription(subs.GetSubId()) {
+ xapp.Logger.Error("SubDelResp: Failed to release sequency number. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
+ return
+ }
+ return
+}
+
+func (c *Control) handleSubscriptionDeleteFailure(params *RMRParams) {
+ xapp.Logger.Info("SubDelFail from E2T:%s", params.String())
+
+ payloadSeqNum, err := c.e2ap.GetSubscriptionDeleteFailureSequenceNumber(params.Payload)
+ if err != nil {
+ xapp.Logger.Error("SubDelFail: Unable to get Sequence Number from Payload. Dropping this msg. Err: %v, %s", err, params.String())
+ return
+ }
+ xapp.Logger.Info("SubDelFail: Received payloadSeqNum: %v", payloadSeqNum)
+
+ subs := c.registry.GetSubscription(payloadSeqNum)
+ if subs == nil {
+ xapp.Logger.Error("SubDelFail: Unknown payloadSeqNum. Dropping this msg. PayloadSeqNum: %v, SubId: %v", payloadSeqNum, params.SubId)
+ return
+ }
+
+ trans := subs.GetTransaction()
+ if trans == nil {
+ xapp.Logger.Error("SubDelFail: Unknown trans. Dropping this msg. PayloadSeqNum: %v, SubId: %v", subs.GetSubId(), params.SubId)
+ return
+ }
+
+ c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()))
+
+ responseReceived := trans.CheckResponseReceived()
+ if responseReceived == true {
+ // Subscription Delete timer already received
+ return
+ }
+ if trans.ForwardRespToXapp == true {
+ var subDelRespPayload []byte
+ subDelRespPayload, err = c.e2ap.PackSubscriptionDeleteResponseFromSubDelReq(trans.Payload, subs.GetSubId())
+ if err != nil {
+ xapp.Logger.Error("SubDelFail:Packing SubDelResp failed. Err: %v", err)
+ return
+ }
+
+ // RIC SUBSCRIPTION DELETE RESPONSE
+ c.rmrReplyToSender("SubDelFail to xapp", subs, trans, 12021, subDelRespPayload, len(subDelRespPayload))
+ time.Sleep(3 * time.Second)
+ }
+
+ xapp.Logger.Info("SubDelFail: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
+ trans.Release()
+ if !c.registry.DelSubscription(subs.GetSubId()) {
+ xapp.Logger.Error("SubDelFail: Failed to release sequency number. Err: %v, SubId: %v, Xid: %s", err, subs.GetSubId(), trans.GetXid())
+ return
+ }
+ return
+}
+
+func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int, tryCount uint64) {
+ xapp.Logger.Info("SubDelReq timeout: subId: %v, tryCount: %v", nbrId, tryCount)
+
+ subs := c.registry.GetSubscription(uint16(nbrId))
+ if subs == nil {
+ xapp.Logger.Error("SubDelReq timeout: Unknown payloadSeqNum. Dropping this msg. SubId: %v", nbrId)
+ return
+ }
+
+ trans := subs.GetTransaction()
+ if trans == nil {
+ xapp.Logger.Error("SubDelReq timeout: Unknown trans. Dropping this msg. SubId: %v", subs.GetSubId())
+ return
+ }
+
+ responseReceived := trans.CheckResponseReceived()
+ if responseReceived == true {
+ // Subscription Delete Response or Failure already received
+ return
+ }
+
+ if tryCount < maxSubDelReqTryCount {
+ xapp.Logger.Info("SubDelReq timeout: Resending SubDelReq to E2T: Mtype: %v, SubId: %v, Xid %s, Meid %v", trans.GetMtype(), subs.GetSubId(), trans.GetXid(), trans.GetMeid())
+ // Set possible to handle new response for the subId
+
+ trans.RetryTransaction()
+
+ c.rmrSend("SubDelReq(SubDelReq timer) to E2T", subs, trans, trans.Payload, trans.PayloadLen)
+
+ tryCount++
+ c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(subs.GetSubId()), subReqTime, tryCount, c.handleSubscriptionDeleteRequestTimer)
+ return
+ }
+
+ if trans.ForwardRespToXapp == true {
+ var subDelRespPayload []byte
+ subDelRespPayload, err := c.e2ap.PackSubscriptionDeleteResponseFromSubDelReq(trans.Payload, subs.GetSubId())
+ if err != nil {
+ xapp.Logger.Error("SubDelReq timeout: Unable to pack payload. Dropping this this msg. Err: %v, SubId: %v, Xid: %s, Payload %x", err, subs.GetSubId(), trans.GetXid(), trans.Payload)
+ return
+ }
+
+ // RIC SUBSCRIPTION DELETE RESPONSE
+ c.rmrReplyToSender("SubDelResp(SubDelReq timer) to xapp", subs, trans, 12021, subDelRespPayload, len(subDelRespPayload))
+
+ time.Sleep(3 * time.Second)
+
+ }
+
+ xapp.Logger.Info("SubDelReq timeout: Deleting trans record. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
+ trans.Release()
+ if !c.registry.DelSubscription(subs.GetSubId()) {
+ xapp.Logger.Error("SubDelReq timeout: Failed to release sequency number. SubId: %v, Xid: %s", subs.GetSubId(), trans.GetXid())
+ }