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

Reply via email to