-
Notifications
You must be signed in to change notification settings - Fork 9
Description
UPDATE 15-10-2014
The erroneous behavior is caused by improper use of API, it looks that decision whether to discard the message or add it to @call_ids Queue is taken in queue_msg function (endpoint.rb) which is called right after reception of the message and before incoming_call function is called. Therefore incoming_call is not a proper place to receive further in-dialog INVITEs.
It is still not clear (for me) how to handle such messages and whether it is possible without modifications in the library itself.
The most obvious solution would be to introduce additional instance variable for endpoint which would contain all calls in progress (e.g. @calls_in_progress = {}) and add cid of the call inside the incoming_call function with true value.
When the subsequent in-dialog is received inside recv_msg function, queue_msg would verify if @calls_in_progress contains cid, if true cid would be pushed to @call_ids which would be picked up by incoming_call function and further processing would be possible.
cid would be deleted in the mark_call_dead function when end_call is called by user script.
I am still thinking it through however I wanted to highlight that issue in its original description is outdated and some progress has been made. Still would appreciate any hints on how to simulate this scenario.
ORIGINAL ISSUE
In a transfer related case where multiple reINVITEs are involved it seems that quaff does not work correctly if single entry point for INVITEs is used. If I use a test case like:
...
call.send_response(100, "Trying")
call.send_response(200, "OK")
call.recv_request("ACK")
call.recv_request("INVITE")
call.send_response(200, "OK")
call.recv_request("ACK")
call.recv_request("INVITE")
...
And all the action happens in a single thread test case works as expected.
However if I receive all INVITEs in single point and further logic is determined based on contents of INVITE message all further INVITEs with the Call-ID already received are discarded. The structure of the test case is as follows (a real example is a bit more complex, but problematic section is below):
call_ids = Hash.new(0)
loop do
Thread.start(phone.incoming_call) do |call|
data = call.recv_request("INVITE")
cid = data["message"].header("Call-ID")
if call_ids.has_key? cid
#call already in progress
call_ids[cid] += 1
call.send_response(200, "OK")
call.recv_request("ACK")
if call_ids[cid] == 3
call_ids.delete(cid)
call.end_call
end
elsif !call_ids.has_key? cid
#call is started
call_ids[cid] += 1
call.send_response(100, "Trying")
call.send_response(200, "OK")
call.recv_request("ACK")
elsif ...
While tracing in wireshark I can see second INVITE with the same Call-ID is sent to script but it looks that it gets discarded.
The reason behind writing test case in this way is that script should receive several INVITEs per second and putting all the logic in one leg puts test case in complete disarray when several threads are started at the caller side.
If I am approaching it in the incorrect way could you please point me in the right direction?