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).
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 | calling | 18X | - | 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 | calling | 2XX | - | 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 | ACK | ready | 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 | completing | nua_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. |
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. |
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. |
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. |