SessionS bidirection rpc methods updated, tutorials/fs_evsock config changes

This commit is contained in:
DanB
2018-01-10 17:22:48 +01:00
parent d932e624b3
commit a76a9f4894
8 changed files with 154 additions and 173 deletions

View File

@@ -259,6 +259,7 @@ func (sm *FSSessionManager) Connect() error {
} else {
sm.conns[connId] = fSock
}
utils.Logger.Info(fmt.Sprintf("<%s> successfully connected to FreeSWITCH at: <%s>", utils.FreeSWITCHAgent, connCfg.Address))
go func() { // Start reading in own goroutine, return on error
if err := sm.conns[connId].ReadEvents(); err != nil {
errChan <- err

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package v1
import (
"github.com/cenk/rpc2"
"github.com/cgrates/cgrates/sessionmanager"
"github.com/cgrates/cgrates/utils"
)
@@ -35,12 +36,12 @@ type SessionSv1 struct {
// Publishes BiJSONRPC methods exported by SessionSv1
func (ssv1 *SessionSv1) Handlers() map[string]interface{} {
return map[string]interface{}{
utils.SessionSv1AuthorizeEvent: ssv1.SMG.BiRPCv1AuthorizeEvent,
utils.SessionSv1InitiateSession: ssv1.SMG.BiRPCv1InitiateSession,
utils.SessionSv1UpdateSession: ssv1.SMG.BiRPCv1UpdateSession,
utils.SessionSv1TerminateSession: ssv1.SMG.BiRPCv1TerminateSession,
utils.SessionSv1ProcessCDR: ssv1.SMG.BiRPCv1ProcessCDR,
utils.SessionSv1ProcessEvent: ssv1.SMG.BiRPCv1ProcessEvent,
utils.SessionSv1AuthorizeEvent: ssv1.BiRpcAuthorizeEvent,
utils.SessionSv1InitiateSession: ssv1.BiRpcInitiateSession,
utils.SessionSv1UpdateSession: ssv1.BiRpcUpdateSession,
utils.SessionSv1TerminateSession: ssv1.BiRpcTerminateSession,
utils.SessionSv1ProcessCDR: ssv1.BiRpcProcessCDR,
utils.SessionSv1ProcessEvent: ssv1.BiRpcProcessEvent,
}
}
@@ -72,3 +73,32 @@ func (ssv1 *SessionSv1) ProcessEvent(args *sessionmanager.V1ProcessEventArgs,
rply *sessionmanager.V1ProcessEventReply) error {
return ssv1.SMG.BiRPCv1ProcessEvent(nil, args, rply)
}
func (ssv1 *SessionSv1) BiRpcAuthorizeEvent(clnt *rpc2.Client, args *sessionmanager.V1AuthorizeArgs,
rply *sessionmanager.V1AuthorizeReply) error {
return ssv1.SMG.BiRPCv1AuthorizeEvent(clnt, args, rply)
}
func (ssv1 *SessionSv1) BiRpcInitiateSession(clnt *rpc2.Client, args *sessionmanager.V1InitSessionArgs,
rply *sessionmanager.V1InitSessionReply) error {
return ssv1.SMG.BiRPCv1InitiateSession(clnt, args, rply)
}
func (ssv1 *SessionSv1) BiRpcUpdateSession(clnt *rpc2.Client, args *sessionmanager.V1UpdateSessionArgs,
rply *sessionmanager.V1UpdateSessionReply) error {
return ssv1.SMG.BiRPCv1UpdateSession(clnt, args, rply)
}
func (ssv1 *SessionSv1) BiRpcTerminateSession(clnt *rpc2.Client, args *sessionmanager.V1TerminateSessionArgs,
rply *string) error {
return ssv1.SMG.BiRPCv1TerminateSession(clnt, args, rply)
}
func (ssv1 *SessionSv1) BiRpcProcessCDR(clnt *rpc2.Client, cgrEv utils.CGREvent, rply *string) error {
return ssv1.SMG.BiRPCv1ProcessCDR(clnt, cgrEv, rply)
}
func (ssv1 *SessionSv1) BiRpcProcessEvent(clnt *rpc2.Client, args *sessionmanager.V1ProcessEventArgs,
rply *sessionmanager.V1ProcessEventReply) error {
return ssv1.SMG.BiRPCv1ProcessEvent(clnt, args, rply)
}

View File

@@ -130,16 +130,16 @@ func startCdrc(internalCdrSChan, internalRaterChan chan rpcclient.RpcClientConne
}
}
func startSmGeneric(internalSMGChan, internalRaterChan, internalResourceSChan, internalSupplierSChan,
func startSessionS(internalSMGChan, internalRaterChan, internalResourceSChan, internalSupplierSChan,
internalAttrSChan, internalCDRSChan chan rpcclient.RpcClientConnection, server *utils.Server, exitChan chan bool) {
utils.Logger.Info("Starting CGRateS SMGeneric service.")
utils.Logger.Info("Starting CGRateS Session service.")
var err error
var ralsConns, resSConns, suplSConns, attrSConns, cdrsConn *rpcclient.RpcClientPool
if len(cfg.SessionSCfg().RALsConns) != 0 {
ralsConns, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
cfg.SessionSCfg().RALsConns, internalRaterChan, cfg.InternalTtl)
if err != nil {
utils.Logger.Crit(fmt.Sprintf("<SMGeneric> Could not connect to RALs: %s", err.Error()))
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to RALs: %s", utils.SessionS, err.Error()))
exitChan <- true
return
}
@@ -148,7 +148,7 @@ func startSmGeneric(internalSMGChan, internalRaterChan, internalResourceSChan, i
resSConns, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
cfg.SessionSCfg().ResSConns, internalResourceSChan, cfg.InternalTtl)
if err != nil {
utils.Logger.Crit(fmt.Sprintf("<SMGeneric> Could not connect to ResourceS: %s", err.Error()))
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to ResourceS: %s", utils.SessionS, err.Error()))
exitChan <- true
return
}
@@ -157,7 +157,7 @@ func startSmGeneric(internalSMGChan, internalRaterChan, internalResourceSChan, i
suplSConns, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
cfg.SessionSCfg().SupplSConns, internalSupplierSChan, cfg.InternalTtl)
if err != nil {
utils.Logger.Crit(fmt.Sprintf("<SMGeneric> Could not connect to SupplierS: %s", err.Error()))
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to SupplierS: %s", utils.SessionS, err.Error()))
exitChan <- true
return
}
@@ -166,7 +166,7 @@ func startSmGeneric(internalSMGChan, internalRaterChan, internalResourceSChan, i
attrSConns, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
cfg.SessionSCfg().AttrSConns, internalAttrSChan, cfg.InternalTtl)
if err != nil {
utils.Logger.Crit(fmt.Sprintf("<SMGeneric> Could not connect to AttributeS: %s", err.Error()))
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to AttributeS: %s", utils.SessionS, err.Error()))
exitChan <- true
return
}
@@ -175,21 +175,21 @@ func startSmGeneric(internalSMGChan, internalRaterChan, internalResourceSChan, i
cdrsConn, err = engine.NewRPCPool(rpcclient.POOL_FIRST, cfg.ConnectAttempts, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout,
cfg.SessionSCfg().CDRsConns, internalCDRSChan, cfg.InternalTtl)
if err != nil {
utils.Logger.Crit(fmt.Sprintf("<SMGeneric> Could not connect to RALs: %s", err.Error()))
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to RALs: %s", utils.SessionS, err.Error()))
exitChan <- true
return
}
}
smgReplConns, err := sessionmanager.NewSessionReplicationConns(cfg.SessionSCfg().SessionReplicationConns, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout)
if err != nil {
utils.Logger.Crit(fmt.Sprintf("<SMGeneric> Could not connect to SMGReplicationConnection error: <%s>", err.Error()))
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to SMGReplicationConnection error: <%s>", utils.SessionS, err.Error()))
exitChan <- true
return
}
sm := sessionmanager.NewSMGeneric(cfg, ralsConns, resSConns, suplSConns,
attrSConns, cdrsConn, smgReplConns, cfg.DefaultTimezone)
if err = sm.Connect(); err != nil {
utils.Logger.Err(fmt.Sprintf("<SMGeneric> error: %s!", err))
utils.Logger.Err(fmt.Sprintf("<%s> error: %s!", utils.SessionS, err))
}
// Pass internal connection via BiRPCClient
internalSMGChan <- sm
@@ -213,8 +213,8 @@ func startSmGeneric(internalSMGChan, internalRaterChan, internalResourceSChan, i
}
}
func startSMAsterisk(internalSMGChan chan rpcclient.RpcClientConnection, exitChan chan bool) {
utils.Logger.Info("Starting CGRateS SM-Asterisk service.")
func startAsteriskAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitChan chan bool) {
utils.Logger.Info("Starting Asterisk agent")
smgRpcConn := <-internalSMGChan
internalSMGChan <- smgRpcConn
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessionmanager.SMGeneric))
@@ -292,15 +292,15 @@ func startRadiusAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitCh
exitChan <- true
}
func startSmFreeSWITCH(internalSMGChan chan rpcclient.RpcClientConnection, exitChan chan bool) {
func startFsAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitChan chan bool) {
var err error
utils.Logger.Info("Starting CGRateS SM-FreeSWITCH service")
utils.Logger.Info("Starting FreeSWITCH agent")
smgRpcConn := <-internalSMGChan
internalSMGChan <- smgRpcConn
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessionmanager.SMGeneric))
sm := agents.NewFSSessionManager(cfg.FsAgentCfg(), birpcClnt, cfg.DefaultTimezone)
if err = sm.Connect(); err != nil {
utils.Logger.Err(fmt.Sprintf("<SMFreeSWITCH> error: %s!", err))
utils.Logger.Err(fmt.Sprintf("<%s> error: %s!", utils.FreeSWITCHAgent, err))
}
exitChan <- true
}
@@ -921,12 +921,12 @@ func main() {
// Start SM-Generic
if cfg.SessionSCfg().Enabled {
go startSmGeneric(internalSMGChan, internalRaterChan, internalRsChan,
go startSessionS(internalSMGChan, internalRaterChan, internalRsChan,
internalSupplierSChan, internalAttributeSChan, internalCdrSChan, server, exitChan)
}
// Start SM-FreeSWITCH
if cfg.FsAgentCfg().Enabled {
go startSmFreeSWITCH(internalSMGChan, exitChan)
go startFsAgent(internalSMGChan, exitChan)
// close all sessions on shutdown
go shutdownSessionmanagerSingnalHandler(exitChan)
}
@@ -942,7 +942,7 @@ func main() {
}
if cfg.AsteriskAgentCfg().Enabled {
go startSMAsterisk(internalSMGChan, exitChan)
go startAsteriskAgent(internalSMGChan, exitChan)
}
if cfg.DiameterAgentCfg().Enabled {

View File

@@ -323,7 +323,7 @@ func (self *CGRConfig) checkConfigSanity() error {
}
}
for _, connCfg := range self.RALsThresholdSConns {
if connCfg.Address == utils.MetaInternal && !self.UserServerEnabled {
if connCfg.Address == utils.MetaInternal && !self.thresholdSCfg.Enabled {
return errors.New("ThresholdS not enabled but requested by RALs component.")
}
}

View File

@@ -1,30 +0,0 @@
{
// Contains CDRC template for FreeSWITCH CDR
"cdrc": [
{
"id": "CDRC-FS",
"enabled": true, // enable CDR client functionality
"cdr_in_dir": "/tmp/cgr_fsevsock/cgrates/cdrc/in", // absolute path towards the directory where the CDRs are stored
"cdr_out_dir": "/tmp/cgr_fsevsock/cgrates/cdrc/out", // absolute path towards the directory where processed CDRs will be moved
"cdr_source_id": "fs_csv", // free form field, tag identifying the source of the CDRs within CDRS database
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
{"tag": "tor", "field_id": "ToR", "type": "*composed", "value": "^*voice", "mandatory": true},
{"tag": "accid", "field_id": "OriginID", "type": "*composed", "value": "10", "mandatory": true},
{"tag": "reqtype", "field_id": "RequestType", "type": "*composed", "value": "^*pseudoprepaid", "mandatory": true},
{"tag": "direction", "field_id": "Direction", "type": "*composed", "value": "^*out", "mandatory": true},
{"tag": "tenant", "field_id": "Tenant", "type": "*composed", "value": "^cgrates.org", "mandatory": true},
{"tag": "category", "field_id": "Category", "type": "*composed", "value": "^call", "mandatory": true},
{"tag": "account", "field_id": "Account", "type": "*composed", "value": "12", "mandatory": true},
{"tag": "subject", "field_id": "Subject", "type": "*composed", "value": "12", "mandatory": true},
{"tag": "destination", "field_id": "Destination", "type": "*composed", "value": "2", "mandatory": true},
{"tag": "setup_time", "field_id": "SetupTime", "type": "*composed", "value": "4", "mandatory": true},
{"tag": "answer_time", "field_id": "AnswerTime", "type": "*composed", "value": "5", "mandatory": true},
{"tag": "usage", "field_id": "Usage", "type": "*composed", "value": "~8:s/^(\\d+)$/${1}s/", "mandatory": true},
],
},
],
}

View File

@@ -7,141 +7,120 @@
// This is what you get when you load CGRateS with an empty configuration file.
"listen": {
"rpc_json": ":2012",
"rpc_gob": ":2013",
"http": ":2080",
},
"stor_db": {
"db_password": "CGRateS.org",
},
"scheduler": {
"enabled": true,
},
"rals": {
"enabled": true, // enable Rater service: <true|false>
"cdrstats_conns": [
"enabled": true,
"thresholds_conns": [
{"address": "*internal"}
],
"stats_conns": [
{"address": "*internal"}
],
"pubsubs_conns": [
{"address": "*internal"}
],
"users_conns": [
"attributes_conns": [
{"address": "*internal"}
],
"aliases_conns": [
{"address": "*internal"}
],
},
"stor_db": { // database used to store offline tariff plans and CDRs
"db_password": "CGRateS.org", // password to use when connecting to stordb
},
"scheduler": {
"enabled": true, // start Scheduler service: <true|false>
},
"cdrs": {
"enabled": true, // start the CDR Server service: <true|false>
"cdrstats_conns": [
"enabled": true,
},
"sessions": {
"enabled": true,
"rals_conns": [
{"address": "*internal"}
],
"cdrs_conns": [
{"address": "*internal"}
],
"resources_conns": [
{"address": "*internal"}
],
"suppliers_conns": [
{"address": "*internal"}
],
"attributes_conns": [
{"address": "*internal"}
],
"debit_interval": "10s",
},
"cdrstats": {
"enabled": true, // starts the cdrstats service: <true|false>
},
//"rls": {
// "enabled": true, // starts ResourceLimiter service: <true|false>.
// "cdrstats_conns": [
// {"address": "*internal"}
// ],
//},
"cdre": {
"*default": {
"cdr_format": "csv", // exported CDRs format <csv>
"field_separator": ",",
"data_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from KBytes to Bytes)
"sms_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from SMS unit to call duration in some billing systems)
"generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC unit to call duration in some billing systems)
"cost_multiply_factor": 1, // multiply cost before export, eg: add VAT
"cost_rounding_decimals": -1, // rounding decimals for Cost values. -1 to disable rounding
"cost_shift_digits": 0, // shift digits in the cost on export (eg: convert from EUR to cents)
"mask_destination_id": "MASKED_DESTINATIONS", // destination id containing called addresses to be masked on export
"mask_length": 0, // length of the destination suffix to be masked
"export_dir": "/tmp/cgr_fsevsock/cgrates/cdre", // path where the exported CDRs will be placed
"header_fields": [], // template of the exported header fields
"content_fields": [ // template of the exported content fields
{"tag": "CgrId", "type": "*composed", "value": "CGRID"},
{"tag":"RunId", "type": "*composed", "value": "RunID"},
{"tag":"Tor", "type": "cdrfield", "value": "ToR"},
{"tag":"AccId", "type": "*composed", "value": "OriginID"},
{"tag":"ReqType", "type": "*composed", "value": "RequestType"},
{"tag":"Direction", "type": "*composed", "value": "Direction"},
{"tag":"Tenant", "type": "*composed", "value": "Tenant"},
{"tag":"Category", "type": "*composed", "value": "Category"},
{"tag":"Account", "type": "*composed", "value": "Account"},
{"tag":"Subject", "type": "*composed", "value": "Subject"},
{"tag":"Destination", "type": "*composed", "value": "Destination"},
{"tag":"SetupTime", "type": "*datetime", "value": "SetupTime", "layout": "2006-01-02T15:04:05Z07:00"},
{"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"},
{"tag":"Usage", "type": "*datetime", "value": "Usage"},
{"tag":"Cost", "type": "*composed", "value": "Cost"},
],
"trailer_fields": [], // template of the exported trailer fields
},
"customer_tpl": {
"cdr_format": "csv", // exported CDRs format <csv>
"field_separator": ";",
"data_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from KBytes to Bytes)
"sms_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from SMS unit to call duration in some billing systems)
"generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC unit to call duration in some billing systems)
"cost_multiply_factor": 1, // multiply cost before export, eg: add VAT
"cost_rounding_decimals": -1, // rounding decimals for Cost values. -1 to disable rounding
"cost_shift_digits": 0, // shift digits in the cost on export (eg: convert from EUR to cents)
"mask_destination_id": "MASKED_DESTINATIONS", // destination id containing called addresses to be masked on export
"mask_length": 0, // length of the destination suffix to be masked
"export_dir": "/tmp/cgr_fsevsock/cgrates/cdre", // path where the exported CDRs will be placed
"header_fields": [], // template of the exported header fields
"content_fields": [ // template of the exported content fields
{"tag": "CgrId", "type": "*composed", "value": "CGRID"},
{"tag":"AccId", "type": "*composed", "value": "OriginID"},
{"tag":"ReqType", "type": "*composed", "value": "RequestType"},
{"tag":"Tenant", "type": "*composed", "value": "Tenant"},
{"tag":"Category", "type": "*composed", "value": "Category"},
{"tag":"Subject", "type": "*composed", "value": "Account"},
{"tag":"Destination", "type": "*composed", "value": "~Destination:s/^1(\\d+)/+$1/:s/^\\+(\\d+)/00$1/"},
{"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTIme", "layout": "2006-01-02T15:04:05Z07:00"},
{"tag":"Usage", "type": "*composed", "value": "Usage"},
{"tag":"Cost", "type": "*composed", "value": "Cost"},
],
"trailer_fields": [],
},
},
"sm_freeswitch": {
"enabled": true, // starts SessionManager service: <true|false>
"debit_interval": "5s", // interval to perform debits on.
//"rls_conns": [
// {"address": "*internal"}
//],
"channel_sync_interval": "10s",
"event_socket_conns":[ // instantiate connections to multiple FreeSWITCH servers
{"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": 5}
"freeswitch_agent": {
"enabled": true,
"sessions_conns": [
{"address": "*internal"}
],
"event_socket_conns":[
{"address": "10.10.10.204:8021", "password": "ClueCon", "reconnects": 5}
],
},
"pubsubs": {
"enabled": true, // starts PubSub service: <true|false>.
},
"users": {
"enabled": true, // starts User service: <true|false>.
"indexes": ["Uuid"], // user profile field indexes
},
"aliases": {
"enabled": true,
}
},
"attributes": {
"enabled": true,
},
"resources": {
"enabled": true,
"thresholds_conns": [
{"address": "*internal"}
],
},
"stats": {
"enabled": true,
"thresholds_conns": [
{"address": "*internal"}
],
},
"thresholds": {
"enabled": true,
},
"suppliers": {
"enabled": true,
"rals_conns": [
{"address": "*internal"}
],
"resources_conns": [
{"address": "*internal"}
],
"stats_conns": [
{"address": "*internal"}
],
},
}

View File

@@ -26,7 +26,6 @@ import (
"sync"
"time"
"github.com/cenk/rpc2"
"github.com/cgrates/cgrates/cache"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
@@ -1040,6 +1039,7 @@ func (smg *SMGeneric) CallBiRPC(clnt rpcclient.RpcClientConnection,
}
params := []reflect.Value{clntVal, reflect.ValueOf(args),
reflect.ValueOf(reply)}
fmt.Printf("serviceMethod: %s, args: %+v\n", serviceMethod, args)
ret := method.Call(params)
if len(ret) != 1 {
return utils.ErrServerError
@@ -1334,7 +1334,7 @@ type V1AuthorizeReply struct {
}
// BiRPCV1Authorize performs authorization for CGREvent based on specific components
func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt *rpc2.Client,
func (smg *SMGeneric) BiRPCv1AuthorizeEvent(clnt rpcclient.RpcClientConnection,
args *V1AuthorizeArgs, authReply *V1AuthorizeReply) (err error) {
if args.GetMaxUsage {
if smg.rals == nil {
@@ -1410,7 +1410,7 @@ type V1InitSessionReply struct {
}
// BiRPCV2InitiateSession initiates a new session, returns the maximum duration the session can last
func (smg *SMGeneric) BiRPCv1InitiateSession(clnt *rpc2.Client,
func (smg *SMGeneric) BiRPCv1InitiateSession(clnt rpcclient.RpcClientConnection,
args *V1InitSessionArgs, rply *V1InitSessionReply) (err error) {
if args.AllocateResources {
if smg.resS == nil {
@@ -1469,7 +1469,7 @@ type V1UpdateSessionReply struct {
}
// BiRPCV1UpdateSession updates an existing session, returning the duration which the session can still last
func (smg *SMGeneric) BiRPCv1UpdateSession(clnt *rpc2.Client,
func (smg *SMGeneric) BiRPCv1UpdateSession(clnt rpcclient.RpcClientConnection,
args *V1UpdateSessionArgs, rply *V1UpdateSessionReply) (err error) {
if args.UpdateSession {
if smg.rals == nil {
@@ -1513,7 +1513,7 @@ type V1TerminateSessionArgs struct {
}
// BiRPCV1TerminateSession will stop debit loops as well as release any used resources
func (smg *SMGeneric) BiRPCv1TerminateSession(clnt *rpc2.Client,
func (smg *SMGeneric) BiRPCv1TerminateSession(clnt rpcclient.RpcClientConnection,
args *V1TerminateSessionArgs, rply *string) (err error) {
if args.TerminateSession {
if smg.rals == nil {
@@ -1547,7 +1547,7 @@ func (smg *SMGeneric) BiRPCv1TerminateSession(clnt *rpc2.Client,
}
// Called on session end, should send the CDR to CDRS
func (smg *SMGeneric) BiRPCv1ProcessCDR(clnt *rpc2.Client,
func (smg *SMGeneric) BiRPCv1ProcessCDR(clnt rpcclient.RpcClientConnection,
cgrEv utils.CGREvent, reply *string) error {
if err := smg.ProcessCDR(cgrEv.Event); err != nil {
return utils.NewErrServerError(err)
@@ -1570,7 +1570,7 @@ type V1ProcessEventReply struct {
}
// Called on session end, should send the CDR to CDRS
func (smg *SMGeneric) BiRPCv1ProcessEvent(clnt *rpc2.Client,
func (smg *SMGeneric) BiRPCv1ProcessEvent(clnt rpcclient.RpcClientConnection,
args *V1ProcessEventArgs, rply *V1ProcessEventReply) (err error) {
if args.AllocateResources {
if smg.resS == nil {

View File

@@ -531,6 +531,7 @@ const (
AttributeS = "AttributeS"
MetaSessionS = "*sessions"
FreeSWITCHAgent = "FreeSWITCHAgent"
SessionS = "SessionS"
)
//Meta