Loading...
Searching...
No Matches
NUA Event Diagrams

The example diagrams below try to present how to use NUA API with different SIP use cases.

# Basic Call

The SIP following event diagram shows a pretty simple, succesful call case. The nua events and nua function calls are show in the diagram below as well as the SIP messages.

The call setup above assumes parameters NUTAG_AUTOALERT(0), NUTAG_AUTOANSWER(0) on B side, NUTAG_AUTOACK(0) on A side.

Alice Proxy Bob
0 | | |
1 nua_handle() | | |
2 nua_invite() -> |-----INVITE---->| |
3 nua_i_state <- | | |
4 | |-----INVITE---->| -> nua_i_invite
5 |<--100 Trying---| | -> nua_i_state
6 | | |
7 | | |
8 | | |
9 | |<--180 Ringing--| <- nua_respond(180)
10 nua_i_invite <- |<--180 Ringing--| | -> nua_i_state
11 nua_i_state <- | | |
12 | |<--200 OK-------| <- nua_respond(200)
13 nua_i_invite <- |<---200 OK------| | -> nua_i_state
14 nua_i_state <- | | |
15 nua_ack() -> |-----ACK------->| |
16 nua_i_state <- | |-----ACK------->| -> nua_i_ack
17 | | | -> nua_i_state
18 | | |
19 <<====== SIP Session Established =======>>
20 | | |
21 | | |
22 nua_bye() -> |-----BYE------->| |
23 | |-----BYE------->| -> nua_i_bye
24 | |<----200 OK-----| -> nua_i_state
25 nua_r_bye <- |<---200 OK------| |
26 nua_i_state <- | | |
| | |
nua_handle
nua_handle_t * nua_handle(nua_t *nua, nua_hmagic_t *hmagic, tag_type_t, tag_value_t,...)
Create an operation handle.
Definition nua.c:305
nua_invite
void nua_invite(nua_handle_t *nh, tag_type_t, tag_value_t,...)
Place a call using SIP INVITE method.
Definition nua.c:631
nua_respond
void nua_respond(nua_handle_t *nh, int status, char const *phrase, tag_type_t, tag_value_t,...)
Respond to a request with given status code and phrase.
Definition nua.c:874
nua_ack
void nua_ack(nua_handle_t *nh, tag_type_t, tag_value_t,...)
Acknowledge a succesfull response to INVITE request.
Definition nua.c:637
nua_i_bye
@ nua_i_bye
Incoming BYE call hangup.
Definition nua.h:100
nua_i_ack
@ nua_i_ack
Final response to INVITE has been ACKed.
Definition nua.h:92
nua_i_state
@ nua_i_state
Call state has changed.
Definition nua.h:96
nua_r_bye
@ nua_r_bye
Answer to outgoing BYE.
Definition nua.h:131
nua_i_invite
@ nua_i_invite
Incoming call INVITE.
Definition nua.h:90
nua_bye
void nua_bye(nua_handle_t *, tag_type_t, tag_value_t,...)
Hangdown a call.
Definition nua.c:643

# Holding Call

The media (audio, video) can be put on hold. In SIP system this means that application can indicate to the remote end that it is engaged in other activity (another call, for instance) and does not wish to receive media from the remove end.

The call hold is usully implemented using re-INVITE. Re-INVITE is an INVITE request sent on existing SIP session. Both original caller and callee can send re-INVITEs. The main use of re-INVITE is modifying sessions: adding media lines to the session, changing codecs on existing media, and, as you might expect, putting existing media on hold as well as resuming media from hold.

A re-INVITE is sent by calling nua_invite() on handle with existing call. When putting call on hold, the application can include SOATAG_HOLD("audio") or SOATAG_HOLD("video") or SOATAG_HOLD("audio, video") or SOATAG_HOLD("*") as parameters to re-INVITE nua_invite(). (Note that last SOATAG_HOLD() in the tag list will override the SOATAG_HOLD() tags before it.)

Another feature where nua tries to be helpful is autoanswer and auto-ACK on existing sessions: the re-INVITE is automatically responded with 200 OK and ACK is automatically sent. (If the application wants to respond and ACK by itself, it should explicitly set NUTAG_AUTOANSWER(0) and/or NUTAG_AUTOACK(0) in the handle; either include them in nua_invite() or nua_respond() parameters or call nua_set_hparams() explicitly.

Alice Proxy Bob
0 nua_handle() | | |
1 | | |
2 nua_invite() -> |-----INVITE---->| |
3 nua_i_state <- | | |
4 | |-----INVITE---->| -> nua_i_invite
5 |<--100 Trying---| | -> nua_i_state
6 | | |
7 | | |
8 | | |
9 | |<--180 Ringing--| <- nua_respond(180)
10 nua_i_invite <- |<--180 Ringing--| | -> nua_i_state
11 nua_i_state <- | | |
12 | |<--200 OK-------| <- nua_respond(200)
13 nua_i_invite <- |<---200 OK------| | -> nua_i_state
14 nua_i_state <- | | |
15 nua_ack() -> |-----ACK------->| |
16 nua_i_state <- | |-----ACK------->| -> nua_i_ack
17 | | | -> nua_i_state
18 | | |
19 <<== Bi-Directional RTP Established ==>>
20 | | |
21 | | |
22 | |<--INVITE(hold)-| <- nua_invite(..
21 | | | NUTAG_HOLD("*")..)
23 nua_i_invite <- |<-INVITE(hold)--| | -> nua_i_state
25 nua_i_state <- |----200 OK----->| |
26 | |----200 OK----->| -> nua_i_invite
28 | |<-----ACK-------| -> nua_i_state
29 nua_i_ack <- |<----ACK--------| |
24 | | |
30 <<== Uni-Directional RTP Established ==>>
24 | | |
31 | | |
32 | |<--INVITE-------| <- nua_invite(..
21 | | | NUTAG_HOLD(NULL)..)
33 nua_i_invite <- |<--INVITE-------| | -> nua_i_state
35 nua_i_state <- |---200 OK------>| |
36 | |---200 OK------>| -> nua_i_invite
38 | |<----ACK--------| -> nua_i_state
39 nua_i_ack <- |<----ACK--------| |
40 nua_i_state <- | | |
19 <<== Bi-Directional RTP Established ==>>
42 | | |
43 nua_bye() -> |-----BYE------->| |
44 nua_i_state <- | |-----BYE------->| -> nua_i_bye
46 | |<----200 OK-----| -> nua_i_state
47 |<---200 OK------| |
| | |

# Call Transfer

This is the unattended call transfer case.

1st MSC showing Alice's end:

Alice Bob Carol
0 | | |
1 nua_i_invite <- |<-----INVITE--------| |
2 nua_i_state <- | | |
2 | | |
3 nua_respond(180) -> |----180 Ringing---->| |
2 nua_i_state <- | | |
4 | | |
5 nua_respond(200) -> |------200 OK------->| |
6 nua_i_state <- | | |
8 | | |
7 nua_i_ack <- |<-------ACK---------| |
8 nua_i_state <- | | |
9 |<========RTP=======>| |
10 | | |
11 << Alice performs unattended transfer >> |
12 | | |
13 | | |
14 nua_refer() -> |---REFER("r: C")--->| |
15 | | |
16 nua_r_refer <- |<---202 Accepted----| |
17 | | |
18 nua_i_notify <- |<-----NOTIFY--------| |
19 | | |
20 |------200 OK------->| |
21 | |---INVITE("b: A")-->|
23 | | |
22 nua_bye() -> |-------BYE--------->| |
23 | | |
24 nua_r_bye <- |<----200 OK---------| |
25 nua_i_state <- | No RTP Session | |
28 | |<----180 Ringing----|
26 nua_i_notify <- |<- - -NOTIFY - - - -| |
27 | | |
20 |- - - 200 OK- - - ->| |
29 | | |
30 | |<------200 OK-------|
31 | | |
32 | |---------ACK------->|
33 | | RTP |
34 | |<==================>|
35 | | |
36 |<-----NOTIFY--------| |
37 | | |
38 |------200 OK------->| |
| | |
nua_refer
void nua_refer(nua_handle_t *, tag_type_t, tag_value_t,...)
Transfer a call.
Definition nua.c:778
nua_i_notify
@ nua_i_notify
Incoming event NOTIFY.
Definition nua.h:111
nua_r_refer
@ nua_r_refer
Answer to outgoing REFER.
Definition nua.h:133

2nd MSC showing Bobs's end:

Alice Bob (nh1) Bob (nh2) Carol
0 | | | |
1 |<-----INVITE--------| | |
2 | | | |
3 |---180 Ringing----->| | |
4 | | | |
5 |------200 OK------->| | |
6 | | | |
7 |<-------ACK---------| | |
8 | RTP | | |
9 |<==================>| | |
10 | | | |
11<< Alice performs unattended transfer >> | |
12 | | | |
13 | Refer-To:C F5| | |
14 |-REFER------------->| -> nua_i_refer | |
15 | | | |
16 |<-202 Accepted------| | |
17 | | | |
18 |<-----NOTIFY--------| | |
19 | | | |
20 |------200 OK------->| -> nua_r_notify | |
21 | | | |
22 |-------BYE--------->| -> nua_i_bye | |
23 | | -> nua_i_state | |
24 |<----200 OK---------| nua_handle() -> | |
25 | No RTP Session | nua_invite() -> | |
26 | | |--INVITE("b: A")--->|
27 | | | |
28 | | nua_i_invite <- |<--180 Ringing------|
29 | | nua_i_state <- | |
30 | | nua_i_invite <- |<----200 OK---------|
31 | | nua_i_state <- | |
32 | | nua_ack -> |-------ACK--------->|
33 | | | |
34 | | |<=======RTP========>|
35 | | | |
36 |<-----NOTIFY--------| | |
37 | |
38 |------200 OK------->| -> nua_r_notify
39 | | <- nua_handle_destroy
| |
nua_i_refer
@ nua_i_refer
Incoming REFER call transfer.
Definition nua.h:102
nua_r_notify
@ nua_r_notify
Answer to outgoing NOTIFY.
Definition nua.h:143
nua_handle_destroy
void nua_handle_destroy(nua_handle_t *h)
Destroy a handle.
Definition nua.c:919

Bob includes nh1 in nua_invite()/25 as NUTAG_NOTIFY_REFER() parameter.

Open Issue 1:

- how Bob know when to destroy nh1?

# 3GPP Call Model

The 3GPP call model is defined in 3GPP TS 24.229. In order to select only a single codec and ensure that the QoS reservationa are made before the call is alerting, the 3GPP call model employs multiple offer/answer exchanges. It uses 100rel and PRACK (RFC 3262), UPDATE (RFC 3311) and preconditions (RFC 3312) extensions specified by IETF.

The call setup below assumes parameters NUTAG_AUTOALERT(0), NUTAG_AUTOANSWER(0) on B side, NUTAG_AUTOACK(0) on A side.

A B
0 nua_handle() | |
1 nua_invite() -> | |
2 nua_i_state <- |----INVITE (offer)---->|
3 | | -> nua_i_invite
4 | | -> nua_i_state
5 | |
6 | | <- nua_respond(183)
7 nua_i_invite <- |<----183 (answer)------| -> nua_i_state
8 nua_i_state <- | |
9 << single codec is selected now >>
10 |-----PRACK(offer2)---->| -> nua_i_prack
11 | | -> nua_i_state
12 nua_r_prack <- |<--200/PRACK(answer2)--|
13 | |
14 | |
15 << resource reservations are done now >>
16 | |
17 nua_update() -> |----UPDATE (offer3)--->|
18 nua_i_state <- | |
19 nua_i_state <- |<-200/UPDATE (answer3)-| -> nua_i_update
20 | | -> nua_i_state
21 | |
22 | | << B rings >>
23 | |
24 | | <- nua_respond(180)
25 nua_i_invite <- |<---------180----------|
26 nua_i_state <- | |
27 |--------PRACK--------->| -> nua_i_prack
28 nua_r_prack <- |<-----200/PRACK------->| -> nua_i_state
29 | |
30 | | <- nua_respond(200)
31 nua_i_invite <- |<---------200----------| -> nua_i_state
32 nua_i_state <- | |
33 nua_ack() -> | |
34 nua_i_state <- |----------ACK--------->| -> nua_i_ack
35 | | -> nua_i_state
| |
nua_i_prack
@ nua_i_prack
Incoming PRACK.
Definition nua.h:104
nua_i_update
@ nua_i_update
Incoming session UPDATE.
Definition nua.h:106
nua_r_prack
@ nua_r_prack
Answer to outgoing PRACK.
Definition nua.h:137
nua_update
void nua_update(nua_handle_t *, tag_type_t, tag_value_t,...)
Update a call.
Definition nua.c:808

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