package control
import (
- "fmt"
+ "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
- "strconv"
+
"sync"
)
//
//-----------------------------------------------------------------------------
type Subscription struct {
- mutex sync.Mutex
- registry *Registry
- Seq uint16
- Active bool
- //
- Meid *xapp.RMRMeid
- EpList RmrEndpointList
- Trans *Transaction
+ mutex sync.Mutex // Lock
+ valid bool // valid
+ registry *Registry // Registry
+ ReqId RequestId // ReqId (Requestor Id + Seq Nro a.k.a subsid)
+ Meid *xapp.RMRMeid // Meid/RanName
+ EpList xapp.RmrEndpointList // Endpoints
+ RMRRouteCreated bool // Does subscription have RMR route
+ TransLock sync.Mutex // Lock transactions, only one executed per time for subs
+ TheTrans TransactionIf // Ongoing transaction
+ SubReqMsg *e2ap.E2APSubscriptionRequest // Subscription information
+ SubRFMsg interface{} // Subscription information
+ OngoingReqCount int // Subscription create process is ongoing. In merge case it can ongoing for more than one endpoint
+ OngoingDelCount int // Subscription delete process is ongoing. In merge case it can ongoing for more than one endpoint
+ PolicyUpdate bool // This is true when policy subscrition is being updated. Used not to send delete for update after timeout or restart
+ RetryFromXapp bool // Retry form xApp for subscription that already exist
+ SubRespRcvd bool // Subscription response received
+ DeleteFromDb bool // Delete subscription from db
+ NoRespToXapp bool // Send no response for subscription delete to xApp after restart
+ DoNotWaitSubResp bool // Test flag. Response is not waited for Subscription Request
}
-func (s *Subscription) stringImpl() string {
- return "subs(" + strconv.FormatUint(uint64(s.Seq), 10) + "/" + s.Meid.RanName + "/" + s.EpList.String() + ")"
+func (s *Subscription) String() string {
+ meidstr := "N/A"
+ if s.Meid != nil {
+ meidstr = s.Meid.String()
+ }
+ return "subs(" + s.ReqId.String() + "/" + meidstr + "/" + s.EpList.String() + ")"
}
-func (s *Subscription) String() string {
+func (s *Subscription) GetCachedResponse() (interface{}, bool) {
s.mutex.Lock()
defer s.mutex.Unlock()
- return s.stringImpl()
+ return s.SubRFMsg, s.valid
}
-func (s *Subscription) GetSubId() uint16 {
+func (s *Subscription) SetCachedResponse(subRFMsg interface{}, valid bool) (interface{}, bool) {
s.mutex.Lock()
defer s.mutex.Unlock()
- return s.Seq
+ s.SubRFMsg = subRFMsg
+ s.valid = valid
+ return s.SubRFMsg, s.valid
}
-func (s *Subscription) GetMeid() *xapp.RMRMeid {
+func (s *Subscription) GetReqId() *RequestId {
s.mutex.Lock()
defer s.mutex.Unlock()
- if s.Meid != nil {
- return s.Meid
- }
- return nil
+ return &s.ReqId
}
-func (s *Subscription) Confirmed() {
+func (s *Subscription) GetMeid() *xapp.RMRMeid {
s.mutex.Lock()
defer s.mutex.Unlock()
- s.Active = true
+ return s.Meid
}
-func (s *Subscription) UnConfirmed() {
+func (s *Subscription) GetTransaction() TransactionIf {
s.mutex.Lock()
defer s.mutex.Unlock()
- s.Active = false
+ return s.TheTrans
}
-func (s *Subscription) IsConfirmed() bool {
+func (s *Subscription) WaitTransactionTurn(trans TransactionIf) {
+ s.TransLock.Lock()
s.mutex.Lock()
- defer s.mutex.Unlock()
- return s.Active
+ s.TheTrans = trans
+ s.mutex.Unlock()
}
-func (s *Subscription) IsEndpoint(ep *RmrEndpoint) bool {
+func (s *Subscription) ReleaseTransactionTurn(trans TransactionIf) {
s.mutex.Lock()
- defer s.mutex.Unlock()
- return s.EpList.HasEndpoint(ep)
+ if trans != nil && trans == s.TheTrans {
+ s.TheTrans = nil
+ }
+ s.mutex.Unlock()
+ s.TransLock.Unlock()
}
-func (s *Subscription) SetTransaction(trans *Transaction) error {
+func (s *Subscription) IsMergeable(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest) bool {
s.mutex.Lock()
defer s.mutex.Unlock()
- if s.Trans != nil {
- return fmt.Errorf("subs(%s) trans(%s) exist, can not register trans(%s)", s.stringImpl(), s.Trans, trans)
- }
- trans.Subs = s
- s.Trans = trans
-
- if len(s.EpList.Endpoints) == 0 {
- s.EpList.Endpoints = append(s.EpList.Endpoints, trans.RmrEndpoint)
- return s.updateRouteImpl(CREATE)
- } else if s.EpList.HasEndpoint(&trans.RmrEndpoint) == false {
- s.EpList.Endpoints = append(s.EpList.Endpoints, trans.RmrEndpoint)
- return s.updateRouteImpl(MERGE)
+ if s.valid == false {
+ return false
}
- return nil
-}
-func (s *Subscription) UnSetTransaction(trans *Transaction) bool {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- if trans == nil || trans == s.Trans {
- s.Trans = nil
- return true
+ if s.SubReqMsg == nil {
+ return false
}
- return false
-}
-func (s *Subscription) GetTransaction() *Transaction {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- return s.Trans
-}
+ if s.Meid.RanName != trans.Meid.RanName {
+ return false
+ }
-func (s *Subscription) updateRouteImpl(act Action) error {
- subRouteAction := SubRouteInfo{act, s.EpList, s.Seq}
- err := s.registry.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
- if err != nil {
- return fmt.Errorf("subs(%s) %s", s.stringImpl(), err.Error())
+ // EventTrigger check
+ if s.SubReqMsg.EventTriggerDefinition.Data.Length != subReqMsg.EventTriggerDefinition.Data.Length {
+ return false
+ }
+ for i := uint64(0); i < s.SubReqMsg.EventTriggerDefinition.Data.Length; i++ {
+ if s.SubReqMsg.EventTriggerDefinition.Data.Data[i] != subReqMsg.EventTriggerDefinition.Data.Data[i] {
+ return false
+ }
}
- return nil
-}
-func (s *Subscription) UpdateRoute(act Action) error {
- s.mutex.Lock()
- defer s.mutex.Unlock()
- return s.updateRouteImpl(act)
-}
+ // Actions check
+ if len(s.SubReqMsg.ActionSetups) != len(subReqMsg.ActionSetups) {
+ return false
+ }
-func (s *Subscription) Release() {
- s.registry.DelSubscription(s.Seq)
- err := s.UpdateRoute(DELETE)
- if err != nil {
- xapp.Logger.Error("%s", err.Error())
+ for _, acts := range s.SubReqMsg.ActionSetups {
+ for _, actt := range subReqMsg.ActionSetups {
+ if acts.ActionId != actt.ActionId {
+ return false
+ }
+ if acts.ActionType != actt.ActionType {
+ return false
+ }
+
+ if acts.ActionType != e2ap.E2AP_ActionTypeReport {
+ return false
+ }
+
+ if acts.RicActionDefinitionPresent != actt.RicActionDefinitionPresent {
+ return false
+ }
+
+ if acts.ActionDefinitionChoice.Data.Length != actt.ActionDefinitionChoice.Data.Length {
+ return false
+ }
+ for i := uint64(0); i < acts.ActionDefinitionChoice.Data.Length; i++ {
+ if acts.ActionDefinitionChoice.Data.Data[i] != actt.ActionDefinitionChoice.Data.Data[i] {
+ return false
+ }
+ }
+ if acts.SubsequentAction.Present != actt.SubsequentAction.Present ||
+ acts.SubsequentAction.Type != actt.SubsequentAction.Type ||
+ acts.SubsequentAction.TimetoWait != actt.SubsequentAction.TimetoWait {
+ return false
+ }
+ }
}
+ return true
}