+ xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
+ }
+
+ return nil
+}
+
+func (c *Control) handleSubscriptionRequest(params *RMRParams) {
+ xapp.Logger.Info("SubReq 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("SubReq: %s, Dropping this msg. %s", err.Error(), params.String())
+ return
+ }
+
+ //
+ //
+ //
+ trans.SubReqMsg, err = c.e2ap.UnpackSubscriptionRequest(params.Payload)
+ if err != nil {
+ xapp.Logger.Error("SubReq: %s Dropping this msg. %s", err.Error(), trans)
+ trans.Release()
+ return
+ }
+
+ //
+ //
+ //
+ subs, err := c.registry.ReserveSubscription(&trans.RmrEndpoint, trans.Meid)
+ if err != nil {
+ xapp.Logger.Error("SubReq: %s, Dropping this msg. %s", err.Error(), trans)
+ trans.Release()
+ return
+ }
+
+ err = subs.SetTransaction(trans)
+ if err != nil {
+ xapp.Logger.Error("SubReq: %s, Dropping this msg. %s", err.Error(), trans)
+ subs.Release()
+ trans.Release()
+ return
+ }
+
+ trans.SubReqMsg.RequestId.Seq = uint32(subs.GetSubId())
+
+ //
+ // TODO: subscription create 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.PackSubscriptionRequest(trans.SubReqMsg)
+ if err != nil {
+ xapp.Logger.Error("SubReq: %s for trans %s", err.Error(), trans)
+ subs.Release()
+ 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)
+
+ c.rmrSend("SubReq to E2T", subs, trans, packedData.Buf, len(packedData.Buf))
+
+ c.timerMap.StartTimer("RIC_SUB_REQ", int(subs.GetSubId()), subReqTime, FirstTry, c.handleSubscriptionRequestTimer)
+ xapp.Logger.Debug("SubReq: Debugging trans table = %v", c.tracker.transactionXappTable)
+ return
+}
+
+func (c *Control) handleSubscriptionResponse(params *RMRParams) {
+ xapp.Logger.Info("SubResp from E2T: %s", params.String())
+
+ //
+ //
+ //
+ SubRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload)
+ if err != nil {
+ xapp.Logger.Error("SubDelReq: %s Dropping this msg. %s", err.Error(), params.String())
+ return
+ }
+
+ //
+ //
+ //
+ subs := c.registry.GetSubscription(uint16(SubRespMsg.RequestId.Seq))
+ if subs == nil && params.SubId > 0 {
+ subs = c.registry.GetSubscription(uint16(params.SubId))
+ }
+
+ if subs == nil {
+ xapp.Logger.Error("SubResp: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", SubRespMsg.RequestId.Seq, params.SubId, params.String())
+ return
+ }
+ xapp.Logger.Info("SubResp: subscription found payloadSeqNum: %d, SubId: %d", SubRespMsg.RequestId.Seq, subs.GetSubId())
+
+ //
+ //
+ //
+ trans := subs.GetTransaction()
+ if trans == nil {
+ xapp.Logger.Error("SubResp: Unknown trans. Dropping this msg. SubId: %d", subs.GetSubId())
+ return
+ }
+
+ trans.SubRespMsg = SubRespMsg
+
+ //
+ //
+ //
+ c.timerMap.StopTimer("RIC_SUB_REQ", int(subs.GetSubId()))
+
+ responseReceived := trans.CheckResponseReceived()
+ if responseReceived == true {
+ // Subscription timer already received
+ return
+ }
+
+ packedData, err := c.e2ap.PackSubscriptionResponse(trans.SubRespMsg)
+ if err != nil {
+ xapp.Logger.Error("SubResp: %s for trans %s", err.Error(), trans)
+ trans.Release()
+ return
+ }
+
+ //Optimize and store packed message to be sent.
+ trans.Payload = packedData.Buf
+ trans.PayloadLen = len(packedData.Buf)
+
+ subs.Confirmed()
+ trans.Release()
+ c.rmrReplyToSender("SubResp to xapp", subs, trans, 12011, trans.Payload, trans.PayloadLen)
+ return
+}
+
+func (c *Control) handleSubscriptionFailure(params *RMRParams) {
+ xapp.Logger.Info("SubFail from E2T: %s", params.String())
+
+ //
+ //
+ //
+ SubFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload)
+ if err != nil {
+ xapp.Logger.Error("SubFail: %s Dropping this msg. %s", err.Error(), params.String())
+ return
+ }
+
+ //
+ //
+ //
+ subs := c.registry.GetSubscription(uint16(SubFailMsg.RequestId.Seq))
+ if subs == nil && params.SubId > 0 {
+ subs = c.registry.GetSubscription(uint16(params.SubId))
+ }
+
+ if subs == nil {
+ xapp.Logger.Error("SubFail: Not valid subscription found payloadSeqNum: %d, SubId: %d. Dropping this msg. %s", SubFailMsg.RequestId.Seq, params.SubId, params.String())
+ return
+ }
+ xapp.Logger.Info("SubFail: subscription found payloadSeqNum: %d, SubId: %d", SubFailMsg.RequestId.Seq, subs.GetSubId())
+
+ //
+ //
+ //
+ trans := subs.GetTransaction()
+ if trans == nil {
+ xapp.Logger.Error("SubFail: Unknown trans. Dropping this msg. SubId: %d", subs.GetSubId())
+ return
+ }
+ trans.SubFailMsg = SubFailMsg
+
+ //
+ //
+ //
+ c.timerMap.StopTimer("RIC_SUB_REQ", int(subs.GetSubId()))
+
+ responseReceived := trans.CheckResponseReceived()
+ if err != nil {
+ return
+ }
+
+ if responseReceived == true {
+ // Subscription timer already received
+ return
+ }
+
+ packedData, err := c.e2ap.PackSubscriptionFailure(trans.SubFailMsg)
+ if err != nil {
+ //TODO error handling improvement
+ xapp.Logger.Error("SubFail: %s for trans %s (continue still)", err.Error(), trans)
+ } else {
+ //Optimize and store packed message to be sent.
+ trans.Payload = packedData.Buf
+ trans.PayloadLen = len(packedData.Buf)
+ c.rmrReplyToSender("SubFail to xapp", subs, trans, 12012, trans.Payload, trans.PayloadLen)
+ time.Sleep(3 * time.Second)