Hi Paulo,
probably I'm doing something wrong
That's true. The problem of your scenario is not the handling of the
OPTIONS. If INVITE would come first, your scenario would ignore it as well.
The explanation follows. It is a bit chicken-and-egg so I'll start from
one point on the circle and we'll get to all of them later.
The basic thing about SIPp which may not be obvious is that the scenario
is actually a program for parallel processing of several (thousands of)
mutually independent threads. Each thread consists one or more SIP
transactions, which sometimes form up a dialog together and sometimes
not. SIPp names these threads simply "calls".
For such a parallel system, there are two important characteristics:
1) what identifies the proper thread to handle an incoming message,
2) what event triggers spawning of an additional thread.
As for 1): the identifier of a thread for SIPp is the contents of the
Call-ID header. Let's suppose we have already several threads (calls)
active. For each of them, SIPp keeps notion about the current phase of
execution of the scenario. When a SIP message arrives from outside, SIPp
compares its Call-ID with the list of active Call-IDs. If it finds it on
the list, it further checks whether the message fits into the current
phase of scenario execution for that Call-ID. If it does, SIPp accepts
the message and moves the scenario ahead accordingly; if it does not,
SIPp reports an "unexpected message" error and terminates that
particular call.
At this moment we come to 2). Currently, there are two hard-coded
behaviours which cannot be combined in a single scenario:
- for UAS scenarios, i.e. those whose first "call handling" statement is
<recv>, the event triggering a spawn of a new thread (call) is an
arrival of a message from outside which meets the following conditions:
- its Call-ID is yet unknown (it is not on the list of active threads)
- its reception is foreseen by the scenario at its beginning.
(thanks to the "optional" flag, it is possible to expect more than one
message type at any step of the scenario, including the beginning).
A new thread is spawned only if both these conditions are met. If the
message which comes in has a yet unknown Call-ID but it is not foreseen
at the scenario's beginning, SIPp reports an "unexpected message" error
and does not create a new call.
- for UAC scenarios, i.e. those whose first "call handling" statement
is <send>, the event triggering a spawn of a new thread (call) is a tick
of the call generation timer controlled by the command-line parameters
specifying call rate. Each time the timer ticks, SIPp generates a new
Call-ID and sends the first message in the scenario with that Call-ID.
UAC scenarios do not use incoming messages with unknown Call-IDs to
spawn new calls, they just report "unexpected message" errors for them.
The above explains the importance of distinction between "UAC scenarios"
and "UAS scenarios" emphasized in the documentation.
Now let's get back to what you want to accomplish. In the simplest case
(just one registration followed by just one incoming call):
- first, you want to register to the user account, which means you need
an UAC scenario, because the first thing you have to do is to send a
REGISTER request. It is your scenario who chooses the time of sending it.
- next, you want to accept and properly react to an INVITE from the
remote equipment, which means you need an UAS scenario, because it is
not your scenario who chooses the time when the INVITE will come.
- in parallel to expecting INVITE, your scenario must also be ready to
accept and properly react to OPTIONS from the remote equipment. Also
here an UAS-like handling is needed as it is not your scenario who
chooses the time when the OPTIONS will come.
Luckily, all three message exchanges as described above are separate
SIPp "calls", i.e. they have a different Call-IDs.
But we've just proven that we need a scenario which acts as UAC for the
first call and as UAS for the rest, which is impossible, so what next?
Currently, the only available solution is to use two scenarios.
In vanilla SIP, you could send a REGISTER from one socket (IP:port) and
indicate another socket in the Contact, so the two scenarios could run
in parallel, each bound to its own socket (try to figure out why they
cannot share a common one). But in most nowadays' service environments,
and definitely in those which send OPTIONS aimed to keep pinholes in
SIP-agnostic firewalls open, the core equipment remembers the socket
from which the REGISTER was sent and sends its own requests to that
socket at UDP level in order to hit the proper pinhole in the firewall,
while indicating the (possibly different) socket from Contact only in
the SIP message body so that the SIP equipment behind the firewall would
accept the message. So in your case, we have to ensure that the REGISTER
will be sent from the same socket on which you will expect the INVITE
and OPTIONS.
The simplest way to do that is to run first the UAC scenario to perform
the registration, and immediately after it the UAS scenario which will
wait for the incoming initial INVITEs and incoming keepalive OPTIONS.
But for more complex cases (e.g., several "phones" registering to their
respective user accounts and then calling each other or even
transferring calls), there is yet another possibility - to use SIPp's
3rd party call control which allows one scenario to affect execution of
another one. You may have noticed that on top of <send> and <recv> which
are related to SIP messages, there are also <sendCmd> and <recvCmd>
which are related to control messages from other SIPp instances, which
are received on their own socket(s) but otherwise handled much like SIP
messages.
So to fully automate your case, you would extend your "INVITE/OPTIONS"
UAS scenario with a third optional path through it, which would begin
with "recvCmd". So your scenario would start with:
<recv request="INVITE" optional="true" next="handle_INVITE"/>
<recv request="OPTIONS" optional="true" next="handle_OPTIONS"/>
<recvCmd/>
<send>
<![CDATA[
REGISTER sip:...
]]>
</send>
This way, the registering thread of this scenario starts with <recv>, so
the SIPp instance running it chooses to run in UAS mode. To send the
REGISTER, this ("main") scenario must first receive a command from
another ("timer") scenario:
<sendCmd>
<![CDATA[
Call-ID: [call_id]
]]>
</sendCmd>
But there are additional things you have to deal with:
- as a scenario must not start from a sendCmd, you have to use a dirty
trick to make the timer scenario run as an UAC one - you must let it
send a SIP message to itself.
- the timer scenario must not end immediately, because it would cause
the main scenario to end as well (it may not seem so at first glance but
it is good that it works like that).
So the whole timer scenario must look at least like this:
<send>
<![CDATA[
INFO sip:...
Call-ID: [call-id]
]]>
</send>
<recv request="INFO"/>
<sendCmd>
<![CDATA[
Call-ID: [call_id]
]]>
</sendCmd>
<pause milliseconds="120000"/>
The command line parameters of the sipp instances running the two
scenarios must tell the instances how to behave:
- both instances must get an indication of the tcp socket on which to
talk to each other "-3pcc localhost:9001" (supposing both run at the
same machine and tcp port 9001 is free; whether sendCmd or recvCmd is
first in the scenario determines whether the instance will be a client
or server on that tcp socket)
- the timer instance must be told to send the SIP messages to itself:
"sipp localhost:5064 -p 5064"
- the timer instance must get the "-m N" command line parameter so that
it would not flood the core with registrations. The N will be 1 for the
simplest case.
While debugging and thus running the two instances manually in separate
windows, it is better to start the main one first. Later, when using
them routinely, you may run them using a batch script. In the script,
run the timer instance first and add "-bg" to its command line
parameters so that it runs at the background, i.e. detached from the
screen. It will not actually start executing until the main instance
will start listening on the communication socket.
As you wrote that you'd like to use one sipp instance to imitate the
called phone, and other sipp instance to imitate the calling one, a
couple of additional remarks:
- I was unable to make the "extended 3pcc control", allowing to push
forward several "executive" instances by a single common timer instance,
work with SIPp 3.2 (maybe even 3.3) on Windows (cygwin). So I've stayed
with two instances (main + timer) for each "phone", and manual start of
each "phone".
- even for the "calling phone" case:
- an INVITE gets often rejected if the phone has not registered
itself first (again, that's not a vanilla SIP behaviour but in reality a
most frequent one), so you must perform the complete registration
procedure first and only then you can start handling the outgoing call.
On top of that, it is highly recommended that the Call-ID of the INVITE
is different from the Call-ID of the REGISTER.
- you have to deal with the incoming OPTIONS.
Therefore, you'll have to use the main + timer scenario also for the
"calling phone" case, let the timer instance start two calls a couple of
seconds apart from each other, and in the "main" scenario, use the ereg
action to extract call order number from the received Call-ID and choose
between the "REGISTER" and "INVITE" path through the scenario. It is not
safe to use the local call_number variable because when you run the
scenario once, the core starts sending OPTIONS and continues doing so
until the registration expires. So if you run the scenario for the
second time, you may receive the OPTIONs before the timing Cmd.
Good luck,
Pavel
Dne 18.12.2015 v 18:38 Paulo Ferreira napsal(a):
Hi Pavel,
I'm facing a similar problem as Fernando does. I'm trying to register
sipp in a VoIP infrastructure and then call them with other sipp, to
test the iPBX. The problem is that the infrastructure I'm using, as
you mentioned, uses OPTIONS to set extension reachability, up or down,
so I sipp must to reply to the OPTIONS as you mentioned. The problem
is SIPp is ignoring OPTIONS entries in my xml, the entries I put there
as you wrote in the reply to Fernando.
------------------------------------------------------------------------------
_______________________________________________
Sipp-users mailing list
Sipp-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sipp-users