mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-15 05:09:54 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -191,7 +191,7 @@ func TestDmtAgentTPFromFolder(t *testing.T) {
|
||||
time.Sleep(time.Duration(1000) * time.Millisecond) // Give time for scheduler to execute topups
|
||||
}
|
||||
|
||||
func TestConnectDiameterClient(t *testing.T) {
|
||||
func TestDmtAgentConnectDiameterClient(t *testing.T) {
|
||||
dmtClient, err = NewDiameterClient(daCfg.DiameterAgentCfg().Listen, "UNIT_TEST", daCfg.DiameterAgentCfg().OriginRealm,
|
||||
daCfg.DiameterAgentCfg().VendorId, daCfg.DiameterAgentCfg().ProductName, utils.DIAMETER_FIRMWARE_REVISION, daCfg.DiameterAgentCfg().DictionariesDir)
|
||||
if err != nil {
|
||||
|
||||
@@ -49,8 +49,9 @@ func NewDiameterClient(addr, originHost, originRealm string, vendorId int, produ
|
||||
RetransmitInterval: time.Second,
|
||||
EnableWatchdog: true,
|
||||
WatchdogInterval: 5 * time.Second,
|
||||
AcctApplicationID: []*diam.AVP{
|
||||
diam.NewAVP(avp.AcctApplicationID, avp.Mbit, 0, datatype.Unsigned32(4)), // RFC 4006
|
||||
AuthApplicationID: []*diam.AVP{
|
||||
// Advertise support for credit control application
|
||||
diam.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4)), // RFC 4006
|
||||
},
|
||||
}
|
||||
if len(dictsDir) != 0 {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<diameter>
|
||||
<application id="4" type="acct">
|
||||
<application id="4" type="auth">
|
||||
<vendor id="10415" name="3GPP" />
|
||||
<avp name="3GPP-Charging-Characteristics" code="13" must="V" may="P" must-not="M" may-encrypt="Y" vendor-id="10415">
|
||||
<data type="UTF8String" />
|
||||
@@ -1373,15 +1373,6 @@
|
||||
<data type="Enumerated">
|
||||
<item code="0" name="WLAN" />
|
||||
<item code="1" name="VIRTUAL" />
|
||||
<item code="1000" name="UTRAN" />
|
||||
<item code="1001" name="GERAN" />
|
||||
<item code="1002" name="GAN" />
|
||||
<item code="1003" name="HSPA_EVOLUTION" />
|
||||
<item code="1004" name="EUTRAN" />
|
||||
<item code="2000" name="CDMA2000_1X" />
|
||||
<item code="2001" name="HRPD" />
|
||||
<item code="2002" name="UMB" />
|
||||
<item code="2003" name="EHRPD" />
|
||||
</data>
|
||||
</avp>
|
||||
<avp name="Read-Reply-Report-Requested" code="1222" must="V,M" may="P" must-not="-" may-encrypt="N" vendor-id="10415">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<diameter>
|
||||
<application id="4" type="acct">
|
||||
<application id="4" type="auth">
|
||||
<!-- Diameter Credit Control Application -->
|
||||
<!-- http://tools.ietf.org/html/rfc4006 -->
|
||||
<command code="272" short="CC" name="Credit-Control">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<diameter>
|
||||
<application id="4" type="acct">
|
||||
<application id="4" type="auth">
|
||||
<vendor id="2011" name="Huawei" />
|
||||
<avp name="IN-Information" code="20300" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="2011">
|
||||
<data type="Grouped">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<diameter>
|
||||
<application id="4" type="acct">
|
||||
<application id="4" type="auth">
|
||||
<!-- Diameter Network Access Server Application -->
|
||||
<!-- http://tools.ietf.org/html/rfc7155 -->
|
||||
<command code="265" short="AA" name="AA">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<diameter>
|
||||
<application id="4" type="acct">
|
||||
<application id="4" type="auth">
|
||||
<vendor id="94" name="Nokia" />
|
||||
<avp name="Session-Start-Indicator" code="5105" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="94">
|
||||
<data type="UTF8String" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<diameter>
|
||||
<application id="4" type="acct">
|
||||
<application id="4" type="auth">
|
||||
<vendor id="12645" name="Vodafone" />
|
||||
<avp name="Reporting-Reason" code="261" must="V" may="P,M" must-not="-" may-encrypt="N" vendor-id="12645">
|
||||
<data type="Enumerated">
|
||||
|
||||
2
glide.lock
generated
2
glide.lock
generated
@@ -16,7 +16,7 @@ imports:
|
||||
- name: github.com/cgrates/osipsdagram
|
||||
version: 3d6beed663452471dec3ca194137a30d379d9e8f
|
||||
- name: github.com/cgrates/rpcclient
|
||||
version: 80f4346e7b309760e445f0424f0e0ff38538f196
|
||||
version: dddae42e9344e877627cd4b7aba075d63b452c0b
|
||||
- name: github.com/ChrisTrenkamp/goxpath
|
||||
version: 4aad8d0161aae7d17df4755d2c1e86cd1fcaaab6
|
||||
subpackages:
|
||||
|
||||
@@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package sessionmanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -148,8 +147,6 @@ func TestSMGenericEventGetSessionTTL(t *testing.T) {
|
||||
sesTTLMaxDelay := time.Duration(10 * time.Second)
|
||||
if sTTL := smGev.GetSessionTTL(time.Duration(5*time.Second), &sesTTLMaxDelay); sTTL == eSesTTL || sTTL > eSesTTL+sesTTLMaxDelay {
|
||||
t.Errorf("Received: %v", sTTL)
|
||||
} else {
|
||||
fmt.Println(sTTL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
@@ -31,6 +32,7 @@ import (
|
||||
|
||||
// One session handled by SM
|
||||
type SMGSession struct {
|
||||
mux sync.RWMutex // protects the SMGSession in places where is concurrently accessed
|
||||
CGRID string // Unique identifier for this session
|
||||
EventStart SMGenericEvent // Event which started
|
||||
stopDebit chan struct{} // Channel to communicate with debit loops when closing the session
|
||||
@@ -82,6 +84,8 @@ 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, lastUsed *time.Duration) (time.Duration, error) {
|
||||
self.mux.Lock()
|
||||
defer self.mux.Unlock()
|
||||
requestedDuration := dur
|
||||
if lastUsed != nil {
|
||||
self.ExtraDuration = self.LastDebit - *lastUsed
|
||||
@@ -142,7 +146,6 @@ func (self *SMGSession) debit(dur time.Duration, lastUsed *time.Duration) (time.
|
||||
|
||||
// Attempts to refund a duration, error on failure
|
||||
func (self *SMGSession) refund(refundDuration time.Duration) error {
|
||||
|
||||
if refundDuration == 0 { // Nothing to refund
|
||||
return nil
|
||||
}
|
||||
@@ -218,6 +221,8 @@ func (self *SMGSession) mergeCCs() {
|
||||
|
||||
// Session has ended, check debits and refund the extra charged duration
|
||||
func (self *SMGSession) close(endTime time.Time) (err error) {
|
||||
self.mux.Lock()
|
||||
defer self.mux.Unlock()
|
||||
if len(self.CallCosts) != 0 { // We have had at least one cost calculation
|
||||
chargedEndTime := self.CallCosts[len(self.CallCosts)-1].GetEndTime()
|
||||
if endTime.After(chargedEndTime) { // we did not charge enough, make a manual debit here
|
||||
@@ -262,6 +267,8 @@ func (self *SMGSession) saveOperations(cgrID string) error {
|
||||
if len(self.CallCosts) == 0 {
|
||||
return nil // There are no costs to save, ignore the operation
|
||||
}
|
||||
self.mux.Lock()
|
||||
self.mux.Unlock()
|
||||
cc := self.CallCosts[0] // was merged in close method
|
||||
cc.Round()
|
||||
roundIncrements := cc.GetRoundIncrements()
|
||||
@@ -317,6 +324,8 @@ func (self *SMGSession) storeSMCost(smCost *engine.SMCost) error {
|
||||
}
|
||||
|
||||
func (self *SMGSession) AsActiveSession(timezone string) *ActiveSession {
|
||||
self.mux.RLock()
|
||||
defer self.mux.RUnlock()
|
||||
sTime, _ := self.EventStart.GetSetupTime(utils.META_DEFAULT, timezone)
|
||||
aTime, _ := self.EventStart.GetAnswerTime(utils.META_DEFAULT, timezone)
|
||||
pdd, _ := self.EventStart.GetPdd(utils.META_DEFAULT)
|
||||
|
||||
@@ -229,6 +229,8 @@ func (smg *SMGeneric) indexSession(s *SMGSession, passiveSessions bool) {
|
||||
}
|
||||
idxMux.Lock()
|
||||
defer idxMux.Unlock()
|
||||
s.mux.RLock()
|
||||
defer s.mux.RUnlock()
|
||||
for fieldName := range smg.ssIdxCfg {
|
||||
fieldVal, err := utils.ReflectFieldAsString(s.EventStart, fieldName, "")
|
||||
if err != nil {
|
||||
@@ -471,7 +473,18 @@ func (smg *SMGeneric) replicateSessionsWithID(cgrID string, passiveSessions bool
|
||||
}
|
||||
ssMux.RLock()
|
||||
ss := ssMp[cgrID]
|
||||
if len(ss) != 0 {
|
||||
ss[0].mux.RLock() // lock session so we can clone it after releasing the map lock
|
||||
}
|
||||
ssMux.RUnlock()
|
||||
var ssCln []*SMGSession
|
||||
err = utils.Clone(ss, &ssCln)
|
||||
if len(ss) != 0 {
|
||||
ss[0].mux.RUnlock()
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var wg sync.WaitGroup
|
||||
for _, rplConn := range smgReplConns {
|
||||
if rplConn.Synchronous {
|
||||
@@ -484,7 +497,7 @@ func (smg *SMGeneric) replicateSessionsWithID(cgrID string, passiveSessions bool
|
||||
if sync {
|
||||
wg.Done()
|
||||
}
|
||||
}(rplConn.Connection, rplConn.Synchronous, ss)
|
||||
}(rplConn.Connection, rplConn.Synchronous, ssCln)
|
||||
}
|
||||
wg.Wait() // wait for synchronous replication to finish
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user