New features you'd like see on SIP Sorcery
-
MikeTelis
- Posts: 1582
- Joined: Wed Jul 30, 2008 6:48 am
Post
by MikeTelis » Sun Aug 30, 2009 7:08 am
I've noticed that "overall time-out" parameter I had been using on MSS doesn't work on Sipsorcery. Is there any other way?
I'm talking about:
sys.Dial("me@local",30)
where 30 means that the call must be terminated if not answered within 30 sec.
What I'm trying to do is to write a chunk of code informing me of missed calls. I think that having time-out parameter in sys.Dial won't be enough: sometimes the caller will hangup
before I answer incoming call and SS will abort my script.
I checked out this construction:
Code: Select all
begin
# call processing
rescue
if sys.In
#notify of missed call
end
end
Of course, I should do more checking (besides sys.In) to determine if the call was aborted because the caller hang up. Is there any ready-made function, system variable or something like that?
-
Aaron
- Site Admin
- Posts: 4652
- Joined: Thu Jul 12, 2007 12:13 am
Post
by Aaron » Sun Aug 30, 2009 9:29 am
I've checked that function and it's working correctly on my test.
Regards,
Aaron
-
MikeTelis
- Posts: 1582
- Joined: Wed Jul 30, 2008 6:48 am
Post
by MikeTelis » Sun Aug 30, 2009 6:11 pm
Interesting... will double-check that (apparently I was fooled by the fact you removed this parameter from sys.Dial description in Sipsorcery dialplan help.
Anyway, even if it works, it won't solve the problem. Let me try to explain again. Suppose I received an incoming call and routed it to my ATA using sys.Dial command. I pick-up the phone, you terminate Ruby script, everybody's happy. Now, suppose the caller dropped call before I answered it -- you also terminate Ruby script, but this case is different for me as a user, because I actually missed incoming call (and I want to send a notification of this sad fact).
Thus, I need to distinguish between a case where sys.Dial completed normally (200 OK) and when you aborted it due to some other reason. Note putting some code after sys.Dial isn't a solution because you actually abort Ruby and the only way to intercept this situation is by "rescue" clause.
Hope my question is more or less clear now.
Sincerely,
Mike
-
MikeTelis
- Posts: 1582
- Joined: Wed Jul 30, 2008 6:48 am
Post
by MikeTelis » Sun Aug 30, 2009 6:52 pm
Update: I checked and indeed, time-out parameter is accepted and processed, control gets back to my Ruby script. I call the following procedure after sys.Dial:
Code: Select all
def status
if (ptr = sys.LastDialled[0]).nil?
@code = 487; @reason = 'Cancelled by Sipsorcery'
else
ptr = ptr.TransactionFinalResponse
@code = ptr.StatusCode; @reason = ptr.ReasonPhrase
# sys.Log("#{ptr.ToString()}")
end
end
and it fails with the following error message:
undefined method `StatusCode' for nil:NilClass
I believe it's a bug in your code, please check.
-
MikeTelis
- Posts: 1582
- Joined: Wed Jul 30, 2008 6:48 am
Post
by MikeTelis » Thu Sep 03, 2009 2:43 pm
Yet another update: I found a solution. Here it is:
Code: Select all
# ***************************** S T A T U S ******************************
def status
begin
if (ptr = sys.LastDialled[0]).nil?
@code = 487; @reason = 'Cancelled by Sipsorcery'
else
ptr = ptr.TransactionFinalResponse
@code = ptr.StatusCode; @reason = ptr.ReasonPhrase
# sys.Log("#{ptr.ToString()}")
end
rescue
@code = 480; @reason = 'No answer'
end
end
# ******************************* M A I N ********************************
begin
if sys.In
# ... processing incoming call ...
name = req.Header.From.FromName.to_s # create a copy of FromName
else
# ... processing outgoing call ...
end
rescue
if $!.to_s =~ /Thread was being aborted./
status() # check call status
if sys.In && (@code > 200)
sys.Email 'myemail@address.com',"Missed call from #{name}",<<-ENDOFMSG
Hi Mike,
you missed a call from:
Host: #{req.Header.from.FromURI.Host}
User: #{req.Header.from.FromURI.User}
Name: #{req.Header.From.FromName}
Rejected with code #{@code}, reason '#{@reason}'
ENDOFMSG
end # sys.In
else
# Gives a lot more details at what went wrong (borrowed from Myatus' dialplan)
sys.Log("** Error: " + $!)
end
end
The code works but do I feel satisfied? Gosh, no! The above looks more like a patch rather than a neat, lean code. I still believe that sys.LastDialled[0].TransactionFinalResponse.StatusCode must be defined and set when we return from sys.Dial due to time-out. And it should be set to something when processing of incoming call by Ruby script is aborted because the caller dropped the call.
A wish? I suggest that we have a method (something like sys.WasConnected) returning true if sys.Dial completed with OK (code 200) and false otherwise.
A more radical and versatile solution would be in calling a dedicated script when a call (both incoming and outgoing) is terminated. It'd give us a lot of opportunities. The least we could do -- calculate duration of a call.