From 1c5fa996bfdd8f1b959e0ed0338ce2693cb7714a Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Fri, 14 Sep 2012 16:04:15 +0300 Subject: [PATCH] code for unparking the call --- sessionmanager/fsevent.go | 1 + sessionmanager/fssessionmanager.go | 16 ++++++++++++++++ sessionmanager/sessiondelegate.go | 30 ++++++++++++++++++++++++++++++ sessionmanager/sessionmanager.go | 1 + timespans/calldesc.go | 1 + 5 files changed, 49 insertions(+) diff --git a/sessionmanager/fsevent.go b/sessionmanager/fsevent.go index 445cb13d5..16964ac7b 100644 --- a/sessionmanager/fsevent.go +++ b/sessionmanager/fsevent.go @@ -49,6 +49,7 @@ const ( HEARTBEAT = "HEARTBEAT" ANSWER = "CHANNEL_ANSWER" HANGUP = "CHANNEL_HANGUP_COMPLETE" + PARK = "CHANNEL_PARK" ) // Nice printing for the event object. diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 530a2e15d..afba81d4c 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -103,6 +103,8 @@ func (sm *FSSessionManager) readNextEvent(exitChan chan bool) (ev Event) { switch ev.GetName() { case HEARTBEAT: sm.OnHeartBeat(ev) + case PARK: + sm.OnChannelPark(ev) case ANSWER: sm.OnChannelAnswer(ev) case HANGUP: @@ -129,6 +131,11 @@ func (sm *FSSessionManager) DisconnectSession(s *Session) { s.Close() } +// Sends the transfer command to unpark the call to freeswitch +func (sm *FSSessionManager) UnparkCall(uuid, dest string) { + fmt.Fprint(sm.conn, fmt.Sprintf("uuid_transfer %s %s XML rou_cgrates\n\n", uuid, dest)) +} + // Called on freeswitch's hearbeat event func (sm *FSSessionManager) OnHeartBeat(ev Event) { if sm.sessionDelegate != nil { @@ -138,6 +145,15 @@ func (sm *FSSessionManager) OnHeartBeat(ev Event) { } } +// Called on freeswitch's answer event +func (sm *FSSessionManager) OnChannelPark(ev Event) { + if sm.sessionDelegate != nil { + sm.sessionDelegate.OnChannelPark(ev, sm) + } else { + timespans.Logger.Info("park") + } +} + // Called on freeswitch's answer event func (sm *FSSessionManager) OnChannelAnswer(ev Event) { if sm.sessionDelegate != nil { diff --git a/sessionmanager/sessiondelegate.go b/sessionmanager/sessiondelegate.go index 77cfc45ee..a76eecd38 100644 --- a/sessionmanager/sessiondelegate.go +++ b/sessionmanager/sessiondelegate.go @@ -21,6 +21,7 @@ package sessionmanager import ( "fmt" "github.com/cgrates/cgrates/timespans" + "strings" "time" ) @@ -34,6 +35,35 @@ func (rsd *SessionDelegate) OnHeartBeat(ev Event) { timespans.Logger.Info("freeswitch ♥") } +func (rsd *SessionDelegate) OnChannelPark(ev Event, sm SessionManager) { + startTime, err := ev.GetStartTime() + if err != nil { + timespans.Logger.Err("Error parsing answer event start time, using time.Now!") + startTime = time.Now() + } + // if there is no account configured leave the call alone + if strings.TrimSpace(ev.GetAccount()) == "" { + sm.UnparkCall(ev.GetUUID(), ev.GetDestination()) + } + cd := timespans.CallDescriptor{ + Direction: ev.GetDirection(), + Tenant: ev.GetTenant(), + TOR: ev.GetTOR(), + Subject: ev.GetSubject(), + Account: ev.GetAccount(), + Destination: ev.GetDestination(), + TimeStart: startTime} + var remainingTime float64 + err = rsd.Connector.GetMaxSessionTime(cd, &remainingTime) + if err != nil { + timespans.Logger.Err(fmt.Sprintf("Could not get max session time for %v: %v", ev.GetUUID(), err)) + } + if remainingTime == 0 { + timespans.Logger.Info(fmt.Sprintf("Not enough credit for trasferring the call %v.", ev.GetUUID())) + } + sm.UnparkCall(ev.GetUUID(), ev.GetDestination()) +} + func (rsd *SessionDelegate) OnChannelAnswer(ev Event, s *Session) { timespans.Logger.Info("freeswitch answer") } diff --git a/sessionmanager/sessionmanager.go b/sessionmanager/sessionmanager.go index 81c41250c..54bf6b342 100644 --- a/sessionmanager/sessionmanager.go +++ b/sessionmanager/sessionmanager.go @@ -24,6 +24,7 @@ import ( type SessionManager interface { DisconnectSession(*Session) + UnparkCall(string, string) GetSessionDelegate() *SessionDelegate GetDbLogger() timespans.DataStorage } diff --git a/timespans/calldesc.go b/timespans/calldesc.go index ce2b22535..f4002d83c 100644 --- a/timespans/calldesc.go +++ b/timespans/calldesc.go @@ -286,6 +286,7 @@ func (cd *CallDescriptor) GetCost() (*CallCost, error) { Returns the approximate max allowed session for user balance. It will try the max amount received in the call descriptor and will decrease it by 10% for nine times. So if the user has little credit it will still allow 10% of the initial amount. If the user has no credit then it will return 0. +If the user has postpayied plan it returns -1. */ func (cd *CallDescriptor) GetMaxSessionTime() (seconds float64, err error) { _, err = cd.LoadActivationPeriods()