NUA Call Model

The NUA call follows a relatively simple state model presented below.

The call model is used to present changes in call: when media starts to flow, when call is considered established, when call is terminated.

In the figure below, a simplified state diagram for a SIP call is presented. After the call state has changes the application will receive an nua_i_state event indicating the change. The states in NUA call model are represented by enum nua_callstate, and the current value of state is included as the tag NUTAG_CALLSTATE() with the nua_i_state event.

The RFC 3264 SDP Offer/Answer negotiation status is also included in the nua_i_state event. The negotiation status includes the local SDP (in SOATAG_LOCAL_SDP()) sent and flags indicating whether the local SDP was an offer or answer (NUTAG_OFFER_SENT(), NUTAG_ANSWER_SENT()). Likewise, the received remote SDP is included in tag SOATAG_REMOTE_SDP() and flags indicating whether the remote SDP was an offer or an answer in tags NUTAG_OFFER_RECV() or NUTAG_ANSWER_RECV(). SOATAG_ACTIVE_AUDIO() and SOATAG_ACTIVE_VIDEO() are informational tags used to indicate what is the status of these media.

The nua_i_state event is not sent, however, if the change is invoked by application calling API functions like nua_bye() and there is no change in SDP offer/answer status.

                    +---------------+
             +------|     INIT      |-----+
    INVITE/- |      +---------------+     | INVITE/100
             V                            |
       +------------+               +------------+
  +----|  CALLING   |--+        +---|  RECEIVED  |--+
  |    +------------+  |        |   +------------+  |
  |          |         |        |         |         |
  |          | 18X/-   |        |         | -/18X   |
  |          V         |        |         V         |
  |    +------------+  |        |   +------------+  |
  |<---| PROCEEDING |  |        |   |   EARLY    |->|
  |    +------------+  |        |   +------------+  |  -/[3456]XX
  |          |         |        |         |         |
  |          | 2XX/-   | 2XX/-  | -/2XX   | -/2XX   |    or
  |          V         |        |         V         |
  |    + - - - - - -+  |        |   +------------+  |  CANCEL/200,487
  |    : COMPLETING :<-+        +-->|  COMPLETE  |  |
  |    + - - - - - -+               +------------+  |
  |          |                            |         |
  |          | -/ACK                ACK/- |         |
  |          |                            |         |
  |          |                            |         |
  |          |      +---------------+     |         |
  |          +----->|     READY     |<----+         |
  |                 +---------------+               |
  |                   |           |                 |
  |          BYE/200  |           | -/BYE           |
  |                   |           |                 |
  |                   |           V                 |
  |                   |   +--------------+          |
  | [3456]XX/ACK      |   | TERMINATING  |          |
  |                   |   +--------------+          |
  |                   |           |                 |
  |                   |           | [23456]XX/-     |
  |                   V           V                 |
  |                 +---------------+               |
  +---------------->|  TERMINATED   |<--------------+
                    +---------------+

The labels "input/output" along each transition indicates SIP messages received from and sent to network, for instance, state transition "INVITE/100" occurs when a SIP INVITE request is received, and it is immediately returned a 100 (Trying) response. Label "2XX" means any 200-series response, e.g., 200 OK or 202 Accepted). Notation "[3456]XX" means any final error response in 300, 400, 500, or 600 series. Label "18X" means any provisional response from 101 to 199, most typically 180 (Ringing) or 183 (Session Progress).

Detailed Client Call Model

The detailed call model at client side is presented below. This model does not include the extensions like 100rel or UPDATE.

            +------------+
            |    INIT    |
            +------------+
                  |
                 (1) nua_invite/INVITE
                  |
                  V
            +------------+
            |            |-----------------------------(6a)-----+
            |            |----+  nua_cancel                     |
     +------|  CALLING   |  (7a)  /CANCEL                       |
     |      |            |<---+                                 |
     |      |            |----------------------+               |
     |      +------------+                      |               |
     |            |                           (8a) nua_bye      |
     |           (2) 18X/-                      |   /CANCEL     |
     |            |                             |               |
     |            V                             |               |
     |      +------------+                      |               |
     |      |            |-----------------------------(6b)---->|
     |      |            |----+  nua_cancel     |               |
     |      | PROCEEDING |  (7b)  /CANCEL       |               |
     |      |            |<---+                 |               |
     |      |            |----------------------+               |
     |      +------------+                      |               |
     |            |                             |               |
   (3a) 2XX/-   (3b) 2XX/-                      |              (6) [3456]XX/ACK
     |            |                             |               |
     |            V                             |               |
     |      + - - - - - -+                      |               |
     +----->:            :                      |               |
            : COMPLETING :-------+              |               |
     + - - -:            :       |              |               |
     :      + - - - - - -+       |              |               |
     :            |              |              |               |
     :<auto_ack>  |              |              |               |
     :or nua_ack  | <auto_ack>   |              |               |
     :and media   | or nua_ack   | nua_bye      |               |
    (5) error    (4) /ACK       (9) /ACK+BYE  (8b) nua_bye/BYE  |
     : /ACK+BYE   |              |              |               |
     :            V              |              V               |
     :      +------------+       |       +-------------+        |
     :      |            |       |       |             |        |
     :      |   READY    |       |       | TERMINATING*|        |
     :      |            |       |       |             |        |
     :      +------------+       |       +-------------+        |
     :                           |        |          |          |
     :                           |      (10) 2XX   (11) 3XX 4XX |
     :      +-------------+      |        |   /BYE   |  5XX 6XX |
     :      |             |      V        |          |   /-     |
     + - - >| TERMINATING |<--------------+          |          |
            |             |                          |          |
            +-------------+                          |          |
                  |                                  |          |
                (12) [23456]XX to BYE/-              |          |
                  |                                  |          |
                  V                                  |          |
            +------------+                           |          |
            | TERMINATED |<--------------------------+----------+
            +------------+

The detailed description of state transitions on the client side is as follows:

# Previous state Input Output Next state Offer/ Answer Description
C1 init nua_invite() INVITE calling Generate offer Client application starts call be invoking nua_invite(). By default, stack runs the initial offer/answer step and sends INVITE request with the SDP offer.
C2 calling18X-proceeding (Save answer) Stack receives a 18X response (a provisional response between 101 and 199). It establishes an early dialog with server. If the provisional response contains an SDP answer, a session with early media is established. The caller can be listen to, for instance, ring tone or announcements about call progress using the early media session.
C3a calling2XX -completing Save answer

Client receives a 2XX response (usually 200 OK) indicating that call has been accepted by the server. If there is an SDP session description included with response, it is stored.

Unless the auto-ack mode is explicitly turned off by application the client does not stay in completing state, but proceeds immediately to next state transition.

C3b proceeding
C4 completing nua_ack() or
auto-ack
ACKready Process answer Client sends an ACK request in this state transition. If the initial offer was sent with INVITE, the answer must have been received by this time, usually in the 2XX response. Client now completes the SDP offer-answer exchange and activates the media.
C5 completing nua_ack() or
auto-ack and
media error
ACK
BYE
terminating Process answer If there was a failure in SDP negotiation or other failure with media, the stack will automatically terminate the call. The BYE follows immediately after the ACK.
C6a calling 3XX 4XX
5XX 6XX
ACK* terminated - Call is terminated when client receives a final error response (from 300 to 699) to its INVITE request. In this case, the underlying transaction engine takes care of sending ACK even when application-driven-ack mode is requested by application.
C6b

proceeding

C7a calling nua_cancel() CANCEL calling -

Client can ask server to cancel the call attempt while in calling or proceeding state. There is no direct call state transition caused by nua_cancel(). The call state changes when the server returns a response. After receiving a CANCEL request the server will usually return a 487 Request Terminated response and call is terminated as in previous item.

However, there is a race condition and the server can respond with a succesful 2XX response before receiving CANCEL. In that case, the call is established as usual. It is up to application to terminate the call with nua_bye().

C7b proceeding proceeding
C8a calling nua_bye() CANCEL terminating* -

The call cannot be terminated with BYE before the dialog is established with a non-100 preliminary response. So, instead of a BYE, stack sends a CANCEL request, and enters terminating state.

However, there is a race condition and the server can respond with a succesful 2XX response before receiving CANCEL. If the server responds with a 2XX response, the nua will automatically send a BYE request asking server to terminate the call.

C8b proceeding nua_bye() BYE

Even an early session can be terminated after entering proceeding state with nua_bye(). Stack sends a BYE request, and enters terminating state. Unlike CANCEL, BYE affects only one fork.

However, there is a race condition and the server can respond with a succesful 2XX response before receiving BYE. If the server responds with a 2XX response, the nua will automatically send a BYE request asking server to terminate the call.

C9 completingnua_bye()ACK
BYE
terminating -

If the stack is in completing state (it has already received 2XX response), it will have to ACK the final response, too.

C10 terminating* 2XX
to INVITE
BYE terminating -

There is a race condition between BYE and INVITE. The call may have been re-established with INVITE after BYE was processed. BYE is re-sent and call state transitions to normal terminating state.

C11 terminating* 3XX 4XX
5XX 6XX
to INVITE
- terminated -

The INVITE transaction is completed without a call being created. The call state transitions to terminated state.

C12 terminating 3XX 4XX
5XX 6XX
to BYE
- terminated -

Call is terminated when the final response to the BYE is received.

Detailed Server-Side Call Model

The detailed call model at server side (UAS) is presented below. This model does not include the extensions like 100rel or UPDATE.

                           +----------------------------------+
                           |                INIT              |
                           +----------------------------------+
                             |              :               :
                             |              :               :
                            (1) INVITE/100 (2b) INVITE/18X (3c) INVITE/2XX
                             |              :               :
                             |              :               :
                             V              :               :
                          +------------+    :               :
     +--------------------|            |    :               :
     |                    |  RECEIVED  |--------------+     :
     |    +---------------|            |    :         |     :
     |    |               +------------+    :         |     :
     |    |                           |     :         |     :
     |    |          nua_respond/18X (2a)   :         |     :
     |    |                           |     :         |     :
     |    |                           V     V         |     :
     |    |                          +------------+   |     :
     |<------------------------------|            |   |     :
     |    |<-------------------------|    EARLY   |   |     :
     |    |               +----------|            |   |     :
     |    |               |          +------------+   |     :
     | nua_respond/       |                     |     |     :
    (6) /[3456]XX         |    nua_respond/2XX (3b)  (3a)   :
     |    |               |                     |     |     :
     |    |               |                     V     V     V
     |    |               |                    +-------------+
     |    |               |                    |             |
     |    |               |              +-----|  COMPLETED  |- - +
     |    |               |              |     |             |    :
     |    |               |              |     +-------------+    :
     |    |               |              |            |           :
     |    |               |              |           (4) ACK/-    :
     |    |               |              |            |           :
     |    |               |              |            V           :
     |    |               |              |     +-------------+    :
     |    |               |              |     |             |    :
     |    |               |              |     |    READY    |    :
     |    |               |              |     |             |    :
     |    |               |              |     +-------------+    :
     |    |               |              |                        :
     |   (7) CANCEL/487  (8) BYE/487    (9) BYE/200              (5) timeout
     |    |               |              |                        :     /BYE
     |    |               |              |     +-------------+    :
     |    |               |              |     | TERMINATING |<- -+
     |    |               |              |     +-------------+
     |    |               |              |            |
     |    |               |              |            | [23456]XX/-
     |    |               |              |            |
     |    |               |              |            V
     |    V               V              V     +-------------+
     +---------------------------------------->| TERMINATED  |
                                               +-------------+

The detailed description of state transitions on the server side is as follows:

# Previous state Input Output Next state Offer/ Answer Description
S1 init INVITE 100 Trying received Save offer When a INVITE request for a new call is received, the server creates a fresh call handle for it, responds to the client with 100 Trying and enters in the received state by default. It saves the possible SDP offer included in INVITE and passes it to the application.
S2a received nua_respond() 18X early (Generate early answer) When server returns a preliminary response for the initial INVITE request, a early dialog is created. The server can also send an SDP answer with the preliminary answer and establish an early session, too. It can use the early session to send early media, e.g., ringing tone and announcements towards the client.
S2b init INVITE and auto-alert 180 Ringing Save offer (and generate early answer) When auto-alert option is enabled, stack sends 180 Ringing immediately after receiving INVITE and enters early state.
S3a received nua_respond() 2XX completed Generate answer When the server sends a 2XX response towards the client, it accepts the call. The INVITE transaction is now considered complete but unconfirmed at the server side. If the offer was sent in INVITE request, the answer should be included in the 2XX response.
S3b early
S3c init INVITE and auto-answer 200 OK Save offer and
generate answer
When auto-answer option is enabled, stack send 200 OK immediately after receiving INVITE and enters completed state.
S4 completed ACK - ready - The ready state is entered at server side after receiving ACK request from client, indicating that the client have received server's 2XX response. The call is ready, the INVITE transaction is confirmed.
S5td> completed timeout BYE terminating - If the server does not receive an ACK request in timely fashion, it will terminate the call by sending a BYE request to client.
S6a received nua_respond() 3XX 4XX
5XX 6XX
terminated - The server can reject the call by sending a 3XX, 4XX, 5XX, or 6XX response towards the client. The underlying transaction engine takes care of retransmitting the response when needed. It consumes the ACK response sent by the client, too.
S6b early
S7a received CANCEL 487 Request terminated terminated - The client can cancel the call attempt before it is completed with a CANCEL request. Server returns a 200 OK response to CANCEL and a 487 Request Terminated response to the INVITE transaction and the call is terminated.
S7b early
S8 early BYE 487 to INVITE
200 to BYE
terminated - The client can terminate an early session with a BYE request, too. Like in the CANCEL case above, the server will terminate call immediately, return a 200 OK response to BYE and a 487 Request Terminated response to the INVITE transaction.
S9 completed BYE 200 to BYE terminated - The client can terminate a completed dialog with a BYE request. Server terminates call immediately, returns a 200 OK response to BYE and lets the underlying transaction engine to take care of consuming ACK.

Third Party Call Control

There is an alternative offer-answer model for third party call control (3pcc). The call setup involves a 3rd party, client C, which sends initial INVITE to server A without SDP. The call setup looks perfectly ordinary to server B, however.

        A                       C                       B
        |                       |                       |
        |<-------INVITE---------|                       |
        |                       |                       |
        |                       |                       |
        |------200 (offer)----->|                       |
        |                       |----INVITE (offer)---->|
        |                       |                       |
        |                       |                       |
        |                       |<-----200 (answer)-----|
        |<-----ACK (answer)-----|                       |
        |                       |                       |
        |                       |----------ACK--------->|
        |                       |                       |

The modifications to the call model affect mainly offer-answer model. The detailed description of state transitions for 3pcc on the server side is as follows:

# Previous state Input Output Next state Offer/ Answer Description
S1' init INVITE 100 Trying received - There is no SDP to save.
S2b' init INVITE and auto-alert 180 Ringing early - There is no SDP to save.
S3a' early nua_respond() 2XX completed Generate offer The offer is sent in 200 OK.
S3b' received
S3c' init INVITE and auto-answer 200 OK
S4' completed ACK - ready Save and process answer The answer is processed and media activated after receiving ACK.
S9b' completed ACK and O/A error BYE terminating Save and process answer If the offer/answer negotiation ends in error after the server receives answer in ACK request, the server will have to terminate call by sending a BYE request.

Model for Modifying and Terminating Call

After the SIP session has been established, it can be further modified by INVITE transactions, initiated by either the original client or the original server. These so-called re-INVITE transactions can be used to upgrade session (add new media to it), put the session on hold or resume a held call.

A session can be terminated with a BYE request at any time.

If any in-dialog request (including re-INVITE) fails with certain response code, the session can be considered terminated, too. These response codes are documented with sip_response_terminates_dialog(). In some cases, the session should be terminated gracefully by sending a BYE request after the failed requests.

    +-------------------------------------------------------------+
    |                            READY                            |
    +-------------------------------------------------------------+
      |           |                |                |
      |           |                |                |
     (1) BYE/200 (2) nua_bye/BYE  (4) graceful/BYE (5) fatal/-
      |           |                |                |
      |           V                V                |
      |     +-----------------------------+         |
      |     |         TERMINATING         |         |
      |     +-----------------------------+         |
      |                    |                        |
      |                   (3) [23456]XX/-           |
      |                    |                        |
      V                    V                        V
    +-------------------------------------------------------------+
    |                         TERMINATED                          |
    +-------------------------------------------------------------+

The detailed description of state transitions while call is terminated is as follows:

# Previous state Input Output Next state Description
T1 ready BYE 200 OK terminated When the BYE request is received, the recipient terminates the currently ongoing INVITE transaction, the session and its dialog usage (if there is another dialog usage active, e.g., a subscription creted by REFER.)
T2 ready nua_bye BYE terminating The application terminates the session by calling nua_bye(). All the call-related requests on the dialog are rejected while in terminating state with 487 No Such Call response.
T3 terminating 2XX 3XX 4XX 5XX 6XX - terminated The session is finally terminated when a final response to BYE is received. Note that nua stack does retry BYE requests.
T4 ready "graceful" response BYE terminating A call-related request (re-INVITE, UPDATE, INFO, PRACK, REFER) fails with a response code indicating that the client should gracefully terminate the call.
T5 ready "fatal" response - terminated A call-related request (re-INVITE, UPDATE, INFO, PRACK, REFER) fails with a response code indicating that the call has been terminated.
See also:
http://www.ietf.org/internet-drafts/draft-sparks-sipping-dialogusage-01.txt
sip_response_terminates_dialog()
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Sofia-SIP 1.12.11 - Copyright (C) 2006 Nokia Corporation. All rights reserved. Licensed under the terms of the GNU Lesser General Public License.