Page 1 of 2

sys.CallsInProgress

Posted: Fri Jul 02, 2010 6:02 am
by MikeTelis
Is it possible to add a method returning not only the number of calls in progress for the owner of SS account but also their details? What I'm trying to do is to limit the number of concurrent calls made with particular provider. What I need is something like this:

Code: Select all

calls = sys.CallsInProgress(sys.Username)
count = 0
calls.each do |c|
  count += 1 if c.To =~ /@provider/
end

Re: sys.CallsInProgress

Posted: Fri Jul 02, 2010 12:44 pm
by AviMarcus
I'd really love to do that, too. Most providers that give unlimited trunks only allow one concurrent call per trunk. Above that is sometimes a ridiculous rate...

Re: sys.CallsInProgress

Posted: Sat Jul 03, 2010 11:51 am
by Aaron
I've added a new method called GetCurrentCalls, it will return a list of SIPDialogueAsset objects (see the source for a definition http://sipsorcery.codeplex.com/SourceCo ... 817#299661).

Code: Select all

sys.GetCurrentCalls().each { |call|
 sys.Log("remote user field = " + call.RemoteUserField)
}

Re: sys.CallsInProgress

Posted: Sat Jul 03, 2010 4:00 pm
by MikeTelis
Aaron,

many thanks, it works! I found quite a bit of useful information. Just in case somebody wants to follow my footsteps, the code I used for investigation is below:

Code: Select all

Attributes = %w{
Id
Owner
AdminMemberId
LocalTag
RemoteTag
LocalUserField
RemoteUserField
CallId
CSeq
BridgeId
RemoteTarget
RouteSet
CDRId
CallDurationLimit
Inserted
Direction
SDP
RemoteSDP
TransferMode
}

def callsInProgress()
  str = ''
  
  sys.GetCurrentCalls().each_with_index do |c,i|
    str << "\n*** call \# #{i} ***\n\n"
    Attributes.each { |f| str << ("#{f} = #{c.send(f)}\n") }
  end
  
  sys.Log(str)
end

Re: sys.CallsInProgress

Posted: Sat Jul 03, 2010 6:25 pm
by AviMarcus
Thanks Aaron and Mike!

The info for the current outgoing call provider will be found in one of the two legs (probably the second) under the variable "LocalUserField"
e.g. LocalUserField = <sip:account_name@provider.com>;tag=xxxxxxxxxx

where account_name is the username / auth name for the provider, and I'm guessing provider.com is the login server or the realm, maybe. You'll need a regex to extract the correct information, and probably ignore the tag which seems to be appended.

Re: sys.CallsInProgress

Posted: Sat Jul 03, 2010 6:54 pm
by MikeTelis
There is a problem: if a call hasn't been answered yet, it does not appear in sys.GetCurrentCalls' list. For example, one of my VSPs does not allow to make concurrent calls. Suppose I routed a call thru this VSP, destination phone is ringing and I initiate yet another call which should be routed to the same VSP. I check sys.GetCurrentCalls and the first call isn't there (because the call wasn't answered by the callee), I route next call to the same provider and it would reject it due to "Max no of calls reached".

Is it possible to make sys.GetCurrentCalls to return all calls, not only already answered?

Re: sys.CallsInProgress

Posted: Sun Jul 04, 2010 7:54 am
by Aaron
The calls listed are establisehd calls which means any that are in an in progress or ringing state won't be included. You could keep track of which calls you have in progress using the DBWrite and DBRead functions or just capture the failure response from the VSP.

Re: sys.CallsInProgress

Posted: Sun Jul 04, 2010 8:03 am
by MikeTelis
DBRead/DBWrite does not sound like a good solution because I observed cases where SS server or its Ruby engine was restarted and dialplan terminated without rescue / ensure code executed. What I'm saying, it's impossible to ensure the provider is "unlocked" and besides, since DB transactions are not supported, there always is a possibility of a race ending up in a wrong DB record state. So, I'd rather call this approach "error-prone" and I'd rather not be asking for a trouble.

Checking failure response from the VSP is very reliable but I was hoping that sys.GetCurrentCalls would allow me to to do without it.

Re: sys.CallsInProgress

Posted: Sun Jul 04, 2010 11:00 am
by AviMarcus
Aaron wrote:You could keep track of which calls you have in progress using the DBWrite and DBRead functions or just capture the failure response from the VSP.
If I use dbwrite to say it's in use, then how do I ever unlock it? Once it connects, doesn't the script stop running? Is there some code, e.g. rescue, in ruby that will allow it to continue executing even after a sip200 message? I'm no ruby expert...

Some providers don't have a failure response - they just put you through and charge more. I suppose on callcentric you can disable multiple calls and have a second account you can route through if you were using them.

Re: sys.CallsInProgress

Posted: Sun Jul 04, 2010 12:24 pm
by MikeTelis
MikeTelis wrote:If I use dbwrite to say it's in use, then how do I ever unlock it? Once it connects, doesn't the script stop running? Is there some code, e.g. rescue, in ruby that will allow it to continue executing even after a sip200 message? I'm no ruby expert...
Yes, rescue and ensure code blocks are executed even if the dial plan script is aborted because of successful sys.Dial or sys.Respond. Therefore, they can be used to "unlock" a resource. However, if SS server is rebooted or Ruby engine "recycled" due to memory leak there is a thick chance your ensure block won't be executed and the resource will remain locked.

Thus, unless Aaron will find a way of including "calls in progress" into sys.GetCurrentCalls, the best we can do is use it to resolve obvious cases (where there is already connected call) and either ignore or use other tricks in case the other call's just being connected.

Well, like they said: "We call it a beta because it's better than nothing!" :-)