diff --git a/sessionmanager/smg_event.go b/sessionmanager/smg_event.go index be0d319a7..0e710418c 100644 --- a/sessionmanager/smg_event.go +++ b/sessionmanager/smg_event.go @@ -165,7 +165,11 @@ func (self SMGenericEvent) GetLastUsed(fieldName string) (time.Duration, error) if fieldName == utils.META_DEFAULT { fieldName = utils.LastUsed } - result, _ := utils.ConvertIfaceToString(self[fieldName]) + valStr, hasVal := self[fieldName] + if !hasVal { + return nilDuration, nil + } + result, _ := utils.ConvertIfaceToString(valStr) return utils.ParseDurationWithSecs(result) } diff --git a/sessionmanager/smg_session.go b/sessionmanager/smg_session.go index 7d6238ec5..fc0032821 100644 --- a/sessionmanager/smg_session.go +++ b/sessionmanager/smg_session.go @@ -41,6 +41,7 @@ type SMGSession struct { sessionCds []*engine.CallDescriptor callCosts []*engine.CallCost extraDuration time.Duration // keeps the current duration debited on top of what heas been asked + lastUsage time.Duration // Keep record of the last debit for LastUsed functionality } // Called in case of automatic debits @@ -52,7 +53,7 @@ func (self *SMGSession) debitLoop(debitInterval time.Duration) { return default: } - if maxDebit, err := self.debit(debitInterval); err != nil { + if maxDebit, err := self.debit(debitInterval, nilDuration); err != nil { utils.Logger.Err(fmt.Sprintf(" Could not complete debit opperation on session: %s, error: %s", self.eventStart.GetUUID(), err.Error())) disconnectReason := SYSTEM_ERROR if err.Error() == utils.ErrUnauthorizedDestination.Error() { @@ -75,7 +76,17 @@ func (self *SMGSession) debitLoop(debitInterval time.Duration) { } // Attempts to debit a duration, returns maximum duration which can be debitted or error -func (self *SMGSession) debit(dur time.Duration) (time.Duration, error) { +func (self *SMGSession) debit(dur time.Duration, lastUsed time.Duration) (time.Duration, error) { + if lastUsed != nilDuration && + self.cd.DurationIndex != 0 && + self.lastUsage != lastUsed { + if self.lastUsage > lastUsed { // We have debitted more than we have used, refund in the duration debitted + dur -= self.lastUsage - lastUsed + } else { // We have debitted less than we have consumed, add the difference to duration debitted + dur += lastUsed - self.lastUsage + } + } + self.lastUsage = dur // Reset the lastUsage for later reference // apply correction from previous run dur -= self.extraDuration self.extraDuration = 0 diff --git a/sessionmanager/smgeneric.go b/sessionmanager/smgeneric.go index f9e4e27a7..8da95aa45 100644 --- a/sessionmanager/smgeneric.go +++ b/sessionmanager/smgeneric.go @@ -167,18 +167,20 @@ func (self *SMGeneric) GetLcrSuppliers(gev SMGenericEvent, clnt *rpc2.Client) ([ // Execute debits for usage/maxUsage func (self *SMGeneric) SessionUpdate(gev SMGenericEvent, clnt *rpc2.Client) (time.Duration, error) { + evLastUsed, err := gev.GetLastUsed(utils.META_DEFAULT) + if err != nil { + return nilDuration, err + } evMaxUsage, err := gev.GetMaxUsage(utils.META_DEFAULT, self.cgrCfg.MaxCallDuration) if err != nil { return nilDuration, err } evUuid := gev.GetUUID() for _, s := range self.getSession(evUuid) { - if maxDur, err := s.debit(evMaxUsage); err != nil { + if maxDur, err := s.debit(evMaxUsage, evLastUsed); err != nil { return nilDuration, err - } else { - if maxDur < evMaxUsage { - evMaxUsage = maxDur - } + } else if maxDur < evMaxUsage { + evMaxUsage = maxDur } } return evMaxUsage, nil