* nua: passing the culprit to the dialog usage removal functions
If a session was terminated because of a error response returned to a request (as specified by RFC 5157), the nua_i_state event was not sent. Even with this fix, if a dialog has multiple usages, the event usages can be terminated without any indication to the application. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7816 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
f35f29b1c1
commit
bbb36378b2
|
@ -60,7 +60,9 @@
|
|||
/* Dialog handling */
|
||||
|
||||
static void nua_dialog_usage_remove_at(nua_owner_t*, nua_dialog_state_t*,
|
||||
nua_dialog_usage_t**);
|
||||
nua_dialog_usage_t**,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_dialog_log_usage(nua_owner_t *, nua_dialog_state_t *);
|
||||
|
||||
/**@internal
|
||||
|
@ -331,7 +333,9 @@ nua_dialog_usage_t *nua_dialog_usage_add(nua_owner_t *own,
|
|||
/** @internal Remove dialog usage. */
|
||||
void nua_dialog_usage_remove(nua_owner_t *own,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr)
|
||||
{
|
||||
nua_dialog_usage_t **at;
|
||||
|
||||
|
@ -343,7 +347,7 @@ void nua_dialog_usage_remove(nua_owner_t *own,
|
|||
|
||||
assert(*at);
|
||||
|
||||
nua_dialog_usage_remove_at(own, ds, at);
|
||||
nua_dialog_usage_remove_at(own, ds, at, cr, sr);
|
||||
}
|
||||
|
||||
/** @internal Remove dialog usage.
|
||||
|
@ -353,7 +357,9 @@ void nua_dialog_usage_remove(nua_owner_t *own,
|
|||
static
|
||||
void nua_dialog_usage_remove_at(nua_owner_t *own,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t **at)
|
||||
nua_dialog_usage_t **at,
|
||||
nua_client_request_t *cr0,
|
||||
nua_server_request_t *sr0)
|
||||
{
|
||||
if (*at) {
|
||||
nua_dialog_usage_t *du = *at;
|
||||
|
@ -368,10 +374,10 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
|
|||
SU_DEBUG_5(("nua(%p): removing %s usage%s%s\n",
|
||||
(void *)own, nua_dialog_usage_name(du),
|
||||
o ? " with event " : "", o ? o->o_type :""));
|
||||
du->du_class->usage_remove(own, ds, du);
|
||||
du->du_class->usage_remove(own, ds, du, cr0, sr0);
|
||||
|
||||
/* Destroy saved client request */
|
||||
if (nua_client_is_bound(du->du_cr)) {
|
||||
if (cr0 != du->du_cr && nua_client_is_bound(du->du_cr)) {
|
||||
nua_client_bind(cr = du->du_cr, NULL);
|
||||
|
||||
if (nua_client_is_queued(cr))
|
||||
|
@ -391,8 +397,11 @@ void nua_dialog_usage_remove_at(nua_owner_t *own,
|
|||
|
||||
for (sr = ds->ds_sr; sr; sr = sr_next) {
|
||||
sr_next = sr->sr_next;
|
||||
if (sr->sr_usage == du)
|
||||
nua_server_request_destroy(sr);
|
||||
if (sr->sr_usage == du) {
|
||||
if (sr != sr0)
|
||||
nua_server_request_destroy(sr);
|
||||
sr->sr_usage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
su_home_unref(own);
|
||||
|
@ -454,7 +463,7 @@ void nua_dialog_deinit(nua_owner_t *own,
|
|||
ds->ds_terminating = 1;
|
||||
|
||||
while (ds->ds_usage) {
|
||||
nua_dialog_usage_remove_at(own, ds, &ds->ds_usage);
|
||||
nua_dialog_usage_remove_at(own, ds, &ds->ds_usage, NULL, NULL);
|
||||
}
|
||||
|
||||
nua_dialog_remove(own, ds, NULL);
|
||||
|
|
|
@ -286,12 +286,12 @@ struct nua_client_request
|
|||
|
||||
url_t *cr_target;
|
||||
|
||||
uint32_t cr_seq;
|
||||
|
||||
char const *cr_phrase; /**< Latest status phrase */
|
||||
unsigned short cr_status; /**< Latest status */
|
||||
|
||||
unsigned short cr_retry_count; /**< Retry count for this request */
|
||||
|
||||
uint32_t cr_seq;
|
||||
|
||||
/* Flags used with offer-answer */
|
||||
unsigned short cr_answer_recv; /**< Recv answer in response
|
||||
* with this status.
|
||||
|
@ -382,7 +382,9 @@ typedef struct {
|
|||
nua_dialog_usage_t *du);
|
||||
void (*usage_remove)(nua_owner_t *,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
char const *(*usage_name)(nua_dialog_usage_t const *du);
|
||||
void (*usage_peer_info)(nua_dialog_usage_t *du,
|
||||
nua_dialog_state_t const *ds,
|
||||
|
@ -446,7 +448,9 @@ nua_dialog_usage_t *nua_dialog_usage_get(nua_dialog_state_t const *ds,
|
|||
|
||||
void nua_dialog_usage_remove(nua_owner_t *,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
|
||||
void nua_dialog_deinit(nua_owner_t *own,
|
||||
nua_dialog_state_t *ds);
|
||||
|
|
|
@ -74,8 +74,10 @@ static int nua_notify_usage_add(nua_handle_t *nh,
|
|||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
static void nua_notify_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_notify_usage_refresh(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
|
@ -102,8 +104,8 @@ static char const *nua_notify_usage_name(nua_dialog_usage_t const *du)
|
|||
|
||||
static
|
||||
int nua_notify_usage_add(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
{
|
||||
ds->ds_has_events++;
|
||||
ds->ds_has_notifys++;
|
||||
|
@ -112,8 +114,10 @@ int nua_notify_usage_add(nua_handle_t *nh,
|
|||
|
||||
static
|
||||
void nua_notify_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr)
|
||||
{
|
||||
ds->ds_has_events--;
|
||||
ds->ds_has_notifys--;
|
||||
|
@ -796,7 +800,7 @@ static void nua_notify_usage_refresh(nua_handle_t *nh,
|
|||
NUTAG_SUBSTATE(nua_substate_terminated),
|
||||
TAG_END());
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
}
|
||||
|
||||
/** @interal Shut down NOTIFY usage.
|
||||
|
@ -827,7 +831,7 @@ static int nua_notify_usage_shutdown(nua_handle_t *nh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,8 +60,10 @@ static int nua_publish_usage_add(nua_handle_t *nh,
|
|||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
static void nua_publish_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_publish_usage_refresh(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
|
@ -101,8 +103,11 @@ int nua_publish_usage_add(nua_handle_t *nh,
|
|||
|
||||
static
|
||||
void nua_publish_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr
|
||||
)
|
||||
{
|
||||
struct publish_usage *pu = nua_dialog_usage_private(du);
|
||||
|
||||
|
@ -433,7 +438,7 @@ static void nua_publish_usage_refresh(nua_handle_t *nh,
|
|||
nua_r_publish, NUA_ERROR_AT(__FILE__, __LINE__),
|
||||
NULL);
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
}
|
||||
|
||||
/** @interal Shut down PUBLISH usage.
|
||||
|
@ -454,7 +459,7 @@ static int nua_publish_usage_shutdown(nua_handle_t *nh,
|
|||
}
|
||||
|
||||
/* XXX - report to user */
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,9 @@ static int nua_register_usage_add(nua_handle_t *nh,
|
|||
nua_dialog_usage_t *du);
|
||||
static void nua_register_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_register_usage_peer_info(nua_dialog_usage_t *du,
|
||||
nua_dialog_state_t const *ds,
|
||||
sip_t const *sip);
|
||||
|
@ -196,7 +198,9 @@ static int nua_register_usage_add(nua_handle_t *nh,
|
|||
|
||||
static void nua_register_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr)
|
||||
{
|
||||
nua_registration_t *nr = nua_dialog_usage_private(du);
|
||||
|
||||
|
@ -1050,7 +1054,7 @@ static void nua_register_usage_refresh(nua_handle_t *nh,
|
|||
|
||||
/* Report that we have de-registered */
|
||||
nua_stack_event(nua, nh, NULL, nua_r_register, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
}
|
||||
|
||||
/** @interal Shut down REGISTER usage.
|
||||
|
@ -1078,7 +1082,7 @@ static int nua_register_usage_shutdown(nua_handle_t *nh,
|
|||
if (nr->nr_tport)
|
||||
tport_decref(&nr->nr_tport), nr->nr_tport = NULL;
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,9 @@ static int nua_session_usage_add(nua_handle_t *nh,
|
|||
nua_dialog_usage_t *du);
|
||||
static void nua_session_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_session_usage_refresh(nua_owner_t *,
|
||||
nua_dialog_state_t *,
|
||||
nua_dialog_usage_t *,
|
||||
|
@ -190,6 +192,11 @@ static int nua_session_usage_shutdown(nua_owner_t *,
|
|||
nua_dialog_state_t *,
|
||||
nua_dialog_usage_t *);
|
||||
|
||||
static void signal_call_state_change(nua_handle_t *nh,
|
||||
nua_session_usage_t *ss,
|
||||
int status, char const *phrase,
|
||||
enum nua_callstate next_state);
|
||||
|
||||
static int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags);
|
||||
static int nua_invite_client_complete(nua_client_request_t *cr);
|
||||
|
||||
|
@ -230,15 +237,17 @@ int nua_session_usage_add(nua_handle_t *nh,
|
|||
|
||||
static
|
||||
void nua_session_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr0,
|
||||
nua_server_request_t *sr0)
|
||||
{
|
||||
nua_session_usage_t *ss = nua_dialog_usage_private(du);
|
||||
nua_client_request_t *cr, *cr_next;
|
||||
|
||||
cr = du->du_cr;
|
||||
|
||||
if (cr && cr->cr_orq && cr->cr_status >= 200 &&
|
||||
if (cr != cr0 && cr && cr->cr_orq && cr->cr_status >= 200 &&
|
||||
cr->cr_method == sip_method_invite) {
|
||||
ss->ss_reporting = 1;
|
||||
nua_invite_client_ack(cr, NULL);
|
||||
|
@ -252,7 +261,10 @@ void nua_session_usage_remove(nua_handle_t *nh,
|
|||
if (cr->cr_method != sip_method_invite)
|
||||
continue;
|
||||
|
||||
if (cr == du->du_cr)
|
||||
if (cr == cr0)
|
||||
continue;
|
||||
|
||||
if (cr == du->du_cr && cr->cr_orq)
|
||||
continue;
|
||||
|
||||
if (cr->cr_status < 200) {
|
||||
|
@ -268,7 +280,19 @@ void nua_session_usage_remove(nua_handle_t *nh,
|
|||
cr_next = ds->ds_cr;
|
||||
}
|
||||
|
||||
|
||||
if (ss->ss_state != nua_callstate_terminated &&
|
||||
ss->ss_state != nua_callstate_init &&
|
||||
!ss->ss_reporting) {
|
||||
int status = 0; char const *phrase = "Terminated";
|
||||
|
||||
if (cr0)
|
||||
status = cr0->cr_status, phrase = cr0->cr_phrase ? cr0->cr_phrase : phrase;
|
||||
else if (sr0)
|
||||
status = sr0->sr_status, phrase = sr0->sr_phrase;
|
||||
|
||||
signal_call_state_change(nh, ss, status, phrase, nua_callstate_terminated);
|
||||
}
|
||||
|
||||
ds->ds_has_session = 0;
|
||||
nh->nh_has_invite = 0;
|
||||
nh->nh_active_call = 0;
|
||||
|
@ -306,7 +330,7 @@ void nua_session_usage_destroy(nua_handle_t *nh,
|
|||
nua_session_usage_t *ss)
|
||||
{
|
||||
/* Remove usage */
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, nua_dialog_usage_public(ss));
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, nua_dialog_usage_public(ss), NULL, NULL);
|
||||
|
||||
SU_DEBUG_5(("nua: terminated session %p\n", (void *)nh));
|
||||
}
|
||||
|
@ -349,11 +373,6 @@ static int nh_referral_check(nua_handle_t *nh, tagi_t const *tags);
|
|||
static void nh_referral_respond(nua_handle_t *,
|
||||
int status, char const *phrase);
|
||||
|
||||
static void signal_call_state_change(nua_handle_t *nh,
|
||||
nua_session_usage_t *ss,
|
||||
int status, char const *phrase,
|
||||
enum nua_callstate next_state);
|
||||
|
||||
static
|
||||
int session_get_description(sip_t const *sip,
|
||||
char const **return_sdp,
|
||||
|
@ -380,17 +399,26 @@ int nua_server_retry_after(nua_server_request_t *sr,
|
|||
|
||||
/**@fn void nua_invite(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...);
|
||||
*
|
||||
* Place a call using SIP INVITE method.
|
||||
* Place a call using SIP @b INVITE method.
|
||||
*
|
||||
* Incomplete call can be hung-up with nua_cancel(). Complete or incomplete
|
||||
* calls can be hung-up with nua_bye().
|
||||
* The INVITE method is used to initiate a call between two parties. The
|
||||
* call is also known as <i>SIP session</i>.
|
||||
*
|
||||
* At SIP level the session is represented as @e Dialog, which is a
|
||||
* peer-to-peer association between two SIP User-Agents. The dialog is
|
||||
* established by a successful 2XX response to the INVITE. The dialog is
|
||||
* terminated by BYE transaction, which application can initiate with
|
||||
* nua_bye() call.
|
||||
*
|
||||
* Optionally
|
||||
* - uses early media if NUTAG_EARLY_MEDIA() tag is used with non zero-value
|
||||
* - media parameters can be set by SOA tags
|
||||
* - nua_invite() can be used to change status of an existing call:
|
||||
* - #SOATAG_HOLD tag can be used to list the media that will be put on hold,
|
||||
* the value "*" sets all the media beloginging to the session on hold
|
||||
* An @e early @e dialog is established by an preliminary response
|
||||
* (101..199), such as <i>180 Ringing</i>. An early dialog is terminated
|
||||
* with an error response with response code in range 300...699.
|
||||
*
|
||||
* The media session belonging to the SIP session is usually represented by
|
||||
* SDP, Session Description Protocol. The media session it is usually
|
||||
* established during the call set-up with procedure known as SDP
|
||||
* Offer/Answer exchange, defined by @RFC3264. See <b>Media Session
|
||||
* Handling</b> below for details.
|
||||
*
|
||||
* @param nh Pointer to operation handle
|
||||
* @param tag, value, ... List of tagged parameters
|
||||
|
@ -398,22 +426,30 @@ int nua_server_retry_after(nua_server_request_t *sr,
|
|||
* @return
|
||||
* nothing
|
||||
*
|
||||
* @par Related Tags:
|
||||
* NUTAG_URL() \n
|
||||
* Tags of nua_set_hparams() \n
|
||||
* NUTAG_INCLUDE_EXTRA_SDP() \n
|
||||
* SOATAG_HOLD(), SOATAG_AF(), SOATAG_ADDRESS(),
|
||||
* SOATAG_RTP_SELECT(), SOATAG_RTP_SORT(), SOATAG_RTP_MISMATCH(),
|
||||
* SOATAG_AUDIO_AUX(), \n
|
||||
* SOATAG_USER_SDP() or SOATAG_USER_SDP_STR() \n
|
||||
* See use of tags in <sip_tag.h> below
|
||||
*
|
||||
* @par Events:
|
||||
* #nua_r_invite \n
|
||||
* #nua_i_state (#nua_i_active, #nua_i_terminated) \n
|
||||
* #nua_i_media_error \n
|
||||
* #nua_i_fork \n
|
||||
*
|
||||
* @par Tags:
|
||||
* NUTAG_AUTH_CACHE() \n
|
||||
* NUTAG_AUTOACK() \n
|
||||
* NUTAG_AUTOANSWER() \n
|
||||
* NUTAG_EARLY_MEDIA() \n
|
||||
* NUTAG_ENABLEINVITE() \n
|
||||
* NUTAG_INITIAL_ROUTE(), NUTAG_INITIAL_ROUTE_STR() \n
|
||||
* NUTAG_INVITE_TIMER() \n
|
||||
* NUTAG_MEDIA_ENABLE() \n
|
||||
* NUTAG_MEDIA_FEATURES() \n
|
||||
* NUTAG_MIN_SE() \n
|
||||
* NUTAG_RETRY_COUNT() \n
|
||||
* NUTAG_SERVICE_ROUTE_ENABLE() \n
|
||||
* NUTAG_SESSION_REFRESHER() \n
|
||||
* NUTAG_SESSION_TIMER() \n
|
||||
* NUTAG_SOA_NAME() \n
|
||||
* NUTAG_UPDATE_REFRESH() \n
|
||||
*
|
||||
* @par Populating SIP Request Message with Tagged Arguments
|
||||
* The tagged arguments can be used to pass values for any SIP headers to
|
||||
* the stack. When the INVITE message (or any other SIP message) is created,
|
||||
|
@ -449,7 +485,27 @@ int nua_server_retry_after(nua_server_request_t *sr,
|
|||
* application. At this point, the target URI is stored in the request line,
|
||||
* together with method name ("INVITE") and protocol version ("SIP/2.0").
|
||||
* The initial dialog information is also created: @CallID, @CSeq headers
|
||||
* are generated, if they do not exist, and tag is added to @From header.
|
||||
* are generated, if they do not exist, and an unique tag is added to @From
|
||||
* header.
|
||||
*
|
||||
* @par
|
||||
* For the initial INVITE requests, the @Route headers specified by
|
||||
* SIPTAG_ROUTE()/SIPTAG_ROUTER_STR() tags in nua_handle() and nua_invite()
|
||||
* calls are inserted to the request. Next the initial route set specified
|
||||
* by NUTAG_INITIAL_ROUTE()/NUTAG_INITIAL_ROUTE_STR() tags is prepended to
|
||||
* the route. Finally (unless NUTAG_SERVICE_ROUTE_ENABLE(0) is used) the
|
||||
* @ServiceRoute set received from the registrar is also appended to the
|
||||
* route set of the initial request message.
|
||||
*
|
||||
* @par
|
||||
* Next, the stack generates a @Contact header for the request (Unless the
|
||||
* application already gave a @Contact header or it does not want to use
|
||||
* @Contact and indicates that by including SIPTAG_CONTACT(NULL) or
|
||||
* SIPTAG_CONTACT(SIP_NONE) in the tagged parameters.) If the application
|
||||
* has a registration active, the @Contact header used with registration is
|
||||
* used. Otherwise, the @Contact header is generated from the local IP
|
||||
* address and port number, taking also the values from NUTAG_M_DISPLAY(),
|
||||
* NUTAG_M_FEATURES(), NUTAG_M_PARAMS(), and NUTAG_M_USERNAME().
|
||||
*
|
||||
* @par
|
||||
* For in-dialog INVITE (re-INVITE), the request URI is taken from the
|
||||
|
@ -464,19 +520,6 @@ int nua_server_retry_after(nua_server_request_t *sr,
|
|||
* also added now, if it does not exist.
|
||||
*
|
||||
* @par
|
||||
* Next, the stack generates a @Contact header for the request (Unless the
|
||||
* application already gave a @Contact header or it does not want to use
|
||||
* @Contact and indicates that by including SIPTAG_CONTACT(NULL) or
|
||||
* SIPTAG_CONTACT(SIP_NONE) in the tagged parameters.) If the application
|
||||
* has registered the URI in @From header, the @Contact header used with
|
||||
* registration is used. Otherwise, the @Contact header is generated from the
|
||||
* local IP address and port number.
|
||||
*
|
||||
* @par
|
||||
* For the initial INVITE requests, @ServiceRoute set received from
|
||||
* the registrar is also added to the request message.
|
||||
*
|
||||
* @par
|
||||
* The INVITE request message created by nua_invite() operation is saved as
|
||||
* a template for automatic re-INVITE requests sent by the session timer
|
||||
* ("timer") feature (see NUTAG_SESSION_TIMER() for more details). Please
|
||||
|
@ -485,27 +528,105 @@ int nua_server_retry_after(nua_server_request_t *sr,
|
|||
* dialog-specific headers like @To, @From, and @CallID as well as
|
||||
* preference headers @Allow, @Supported, @UserAgent, @Organization).
|
||||
*
|
||||
* @par Tags Related to SIP Headers and Request-URI
|
||||
* NUTAG_URL(), SIPTAG_REQUEST(), SIPTAG_REQUEST_STR() \n
|
||||
* NUTAG_INITIAL_ROUTE(), NUTAG_INITIAL_ROUTE_STR(),
|
||||
* SIPTAG_ROUTE(), SIPTAG_ROUTE_STR(),
|
||||
* NUTAG_SERVICE_ROUTE_ENABLE() \n
|
||||
* SIPTAG_MAX_FORWARDS(), SIPTAG_MAX_FORWARDS_STR() \n
|
||||
* SIPTAG_PROXY_REQUIRE(), SIPTAG_PROXY_REQUIRE_STR() \n
|
||||
* SIPTAG_FROM(), SIPTAG_FROM_STR() \n
|
||||
* SIPTAG_TO(), SIPTAG_TO_STR() \n
|
||||
* SIPTAG_CALL_ID(), SIPTAG_CALL_ID_STR() \n
|
||||
* SIPTAG_CSEQ(), SIPTAG_CSEQ_STR()
|
||||
* (note that @CSeq value is incremented if request gets retried)\n
|
||||
* SIPTAG_CONTACT(), SIPTAG_CONTACT_STR() \n
|
||||
* SIPTAG_REQUEST_DISPOSITION(), SIPTAG_REQUEST_DISPOSITION_STR() \n
|
||||
* SIPTAG_ACCEPT_CONTACT(), SIPTAG_ACCEPT_CONTACT_STR() \n
|
||||
* SIPTAG_REJECT_CONTACT(), SIPTAG_REJECT_CONTACT_STR() \n
|
||||
* SIPTAG_EXPIRES(), SIPTAG_EXPIRES_STR() \n
|
||||
* SIPTAG_DATE(), SIPTAG_DATE_STR() \n
|
||||
* SIPTAG_TIMESTAMP(), SIPTAG_TIMESTAMP_STR() \n
|
||||
* SIPTAG_SUBJECT(), SIPTAG_SUBJECT_STR() \n
|
||||
* SIPTAG_PRIORITY(), SIPTAG_PRIORITY_STR() \n
|
||||
* SIPTAG_CALL_INFO(), SIPTAG_CALL_INFO_STR() \n
|
||||
* SIPTAG_ORGANIZATION(), SIPTAG_ORGANIZATION_STR() \n
|
||||
* NUTAG_USER_AGENT(), SIPTAG_USER_AGENT() and SIPTAG_USER_AGENT_STR() \n
|
||||
* SIPTAG_IN_REPLY_TO(), SIPTAG_IN_REPLY_TO_STR() \n
|
||||
* SIPTAG_ACCEPT(), SIPTAG_ACCEPT_STR() \n
|
||||
* SIPTAG_ACCEPT_ENCODING(), SIPTAG_ACCEPT_ENCODING_STR() \n
|
||||
* SIPTAG_ACCEPT_LANGUAGE(), SIPTAG_ACCEPT_LANGUAGE_STR() \n
|
||||
* NUTAG_ALLOW(), SIPTAG_ALLOW(), and SIPTAG_ALLOW_STR() \n
|
||||
* NUTAG_EARLY_MEDIA(), SIPTAG_REQUIRE(), and SIPTAG_REQUIRE_STR() \n
|
||||
* NUTAG_SUPPORTED(), SIPTAG_SUPPORTED(), and SIPTAG_SUPPORTED_STR() \n
|
||||
* SIPTAG_ALLOW_EVENTS(), SIPTAG_ALLOW_EVENTS_STR() \n
|
||||
* SIPTAG_PROXY_AUTHORIZATION(), SIPTAG_PROXY_AUTHORIZATION_STR() \n
|
||||
* SIPTAG_AUTHORIZATION(), SIPTAG_AUTHORIZATION_STR() \n
|
||||
* SIPTAG_REFERRED_BY(), SIPTAG_REFERRED_BY_STR() \n
|
||||
* SIPTAG_REPLACES(), SIPTAG_REPLACES_STR() \n
|
||||
* NUTAG_SESSION_TIMER(), NUTAG_SESSION_REFRESHER(),
|
||||
* SIPTAG_SESSION_EXPIRES(), SIPTAG_SESSION_EXPIRES_STR() \n
|
||||
* NUTAG_MIN_SE(), SIPTAG_MIN_SE(), SIPTAG_MIN_SE_STR() \n
|
||||
* SIPTAG_SECURITY_CLIENT(), SIPTAG_SECURITY_CLIENT_STR() \n
|
||||
* SIPTAG_SECURITY_VERIFY(), SIPTAG_SECURITY_VERIFY_STR() \n
|
||||
* SIPTAG_PRIVACY(), SIPTAG_PRIVACY_STR() \n
|
||||
* SIPTAG_MIME_VERSION(), SIPTAG_MIME_VERSION_STR() \n
|
||||
* SIPTAG_CONTENT_TYPE(), SIPTAG_CONTENT_TYPE_STR() \n
|
||||
* SIPTAG_CONTENT_ENCODING(), SIPTAG_CONTENT_ENCODING_STR() \n
|
||||
* SIPTAG_CONTENT_LANGUAGE(), SIPTAG_CONTENT_LANGUAGE_STR() \n
|
||||
* SIPTAG_CONTENT_DISPOSITION(), SIPTAG_CONTENT_DISPOSITION_STR() \n
|
||||
* SIPTAG_HEADER(), SIPTAG_HEADER_STR() \n
|
||||
* SIPTAG_PAYLOAD(), SIPTAG_PAYLOAD_STR() \n
|
||||
*
|
||||
* @par SDP Handling
|
||||
* The initial nua_invite() creates a @ref soa_session_t "soa media session"
|
||||
* unless NUTAG_MEDIA_ENABLE(0) has been given. The SDP description of the
|
||||
* @ref soa_session_t "soa media session" is included in the INVITE request
|
||||
* as message body.
|
||||
* By default the nua_invite() uses an @ref soa_session_t "SOA media
|
||||
* session" object to take care of the Offer/Answer exchange. The SOA can
|
||||
* be disabled with tag NUTAG_MEDIA_ENABLE(0).
|
||||
*
|
||||
* @par
|
||||
* The SDP in a 1XX or 2XX response message is interpreted as an answer,
|
||||
* given to the @ref soa_session_t "soa media session" object for
|
||||
* processing.
|
||||
* The SDP description of the
|
||||
* @ref soa_session_t "soa media session" is included in the INVITE request
|
||||
* as a message body.
|
||||
* The SDP in the message body of the 1XX or 2XX response message is
|
||||
* interpreted as an answer, given to the @ref soa_session_t "soa media
|
||||
* session" object for processing.
|
||||
*
|
||||
* @bug If the INVITE request already contains a message body, SDP is not
|
||||
* added. Also, if the response contains a multipart body, it is not parsed.
|
||||
* added. Also, if the response contains a multipart body, it is not parsed.
|
||||
*
|
||||
* @par Tags Related to SDP Management and Offer/Answer Model:
|
||||
* NUTAG_MEDIA_ENABLE(), \n
|
||||
* NUTAG_INCLUDE_EXTRA_SDP(), \n
|
||||
* SOATAG_HOLD(), SOATAG_AF(), SOATAG_ADDRESS(),
|
||||
* SOATAG_ORDERED_USER(), SOATAG_REUSE_REJECTED(),
|
||||
* SOATAG_RTP_SELECT(), SOATAG_RTP_SORT(), SOATAG_RTP_MISMATCH(),
|
||||
* SOATAG_AUDIO_AUX(), \n
|
||||
* SOATAG_USER_SDP() or SOATAG_USER_SDP_STR() \n
|
||||
*
|
||||
* @par Alternative Call Models
|
||||
* In addition to the basic SIP call model described in @RFC3261 and
|
||||
* @RFC3264, the early media model described in @RFC3262 is available. The
|
||||
* use of 100rel and early media can be use can be forced with
|
||||
* NUTAG_EARLY_MEDIA(1).
|
||||
*
|
||||
* Also, the "precondition" call model described in @RFC3312 is supported at
|
||||
* SIP level, that is, the SIP PRACK and UPDATE requests are sent if
|
||||
* "precondition" is added to the @Require header in the INVITE request.
|
||||
*
|
||||
* Optionally
|
||||
* - uses early media if NUTAG_EARLY_MEDIA() tag is used with non zero-value
|
||||
* - media parameters can be set by SOA tags
|
||||
* - nua_invite() can be used to change status of an existing call:
|
||||
* - #SOATAG_HOLD tag can be used to list the media that will be put on hold,
|
||||
* the value "*" sets all the media beloginging to the session on hold
|
||||
*
|
||||
* @par Authentication
|
||||
* The INVITE request may need authentication. Each proxy or server
|
||||
* requiring authentication can respond with 401 or 407 response. The
|
||||
* nua_authenticate() operation stores authentication information (username
|
||||
* and password) to the handle, and stack tries to authenticate all the rest
|
||||
* of the requests (e.g., PRACK, ACK, UPDATE, re-INVITE, BYE) using same
|
||||
* username and password.
|
||||
* of the requests (e.g., PRACK, ACK, UPDATE, re-INVITE, BYE) using the
|
||||
* stored username and password.
|
||||
*
|
||||
* @sa @ref nua_call_model, #nua_r_invite, #nua_i_state, \n
|
||||
* nua_handle_has_active_call() \n
|
||||
|
@ -803,7 +924,7 @@ static int nua_session_client_response(nua_client_request_t *cr,
|
|||
|
||||
#define LOG3(m) \
|
||||
SU_DEBUG_3(("nua(%p): %s: %s %s in %u %s\n", \
|
||||
(void *)nh, cr->cr_method_name, (m), \
|
||||
(void *)nh, cr->cr_method_name, (m), \
|
||||
received ? received : "SDP", status, phrase))
|
||||
#define LOG5(m) \
|
||||
SU_DEBUG_5(("nua(%p): %s: %s %s in %u %s\n", \
|
||||
|
@ -1445,7 +1566,7 @@ static int nua_session_usage_shutdown(nua_handle_t *nh,
|
|||
break;
|
||||
}
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
@ -1652,11 +1773,7 @@ static int nua_prack_client_report(nua_client_request_t *cr,
|
|||
status, phrase,
|
||||
tags);
|
||||
|
||||
if (!ss || cr->cr_terminated || cr->cr_graceful)
|
||||
return 1;
|
||||
|
||||
if (cr->cr_waiting)
|
||||
/* Do not report call state change if restarting later */
|
||||
if (!ss || cr->cr_terminated || cr->cr_graceful || cr->cr_waiting)
|
||||
return 1;
|
||||
|
||||
if (cr->cr_offer_sent || cr->cr_answer_sent) {
|
||||
|
@ -2231,9 +2348,12 @@ int nua_invite_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
|
||||
if (retval >= 2 || ss == NULL) {
|
||||
/* Session has been terminated. */
|
||||
if (!initial && !neutral)
|
||||
if (!initial && !neutral) {
|
||||
#if 0
|
||||
signal_call_state_change(nh, NULL, status, phrase,
|
||||
nua_callstate_terminated);
|
||||
#endif
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2628,9 +2748,11 @@ int nua_prack_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
retval = nua_base_server_report(sr, tags), sr = NULL; /* destroys sr */
|
||||
|
||||
if (retval >= 2 || ss == NULL) {
|
||||
#if 0
|
||||
signal_call_state_change(nh, NULL,
|
||||
status, phrase,
|
||||
nua_callstate_terminated);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -3155,11 +3277,7 @@ static int nua_update_client_report(nua_client_request_t *cr,
|
|||
status, phrase,
|
||||
tags);
|
||||
|
||||
if (!ss || cr->cr_terminated || cr->cr_graceful)
|
||||
return 1;
|
||||
|
||||
if (cr->cr_waiting)
|
||||
/* Do not report call state change if restarting later */
|
||||
if (!ss || cr->cr_terminated || cr->cr_graceful || cr->cr_waiting)
|
||||
return 1;
|
||||
|
||||
if (cr->cr_offer_sent) {
|
||||
|
@ -3360,8 +3478,10 @@ int nua_update_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
retval = nua_base_server_report(sr, tags), sr = NULL; /* destroys sr */
|
||||
|
||||
if (retval >= 2 || ss == NULL) {
|
||||
#if 0
|
||||
signal_call_state_change(nh, NULL, status, phrase,
|
||||
nua_callstate_terminated);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -3633,7 +3753,8 @@ int nua_bye_server_init(nua_server_request_t *sr)
|
|||
int nua_bye_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
||||
{
|
||||
nua_handle_t *nh = sr->sr_owner;
|
||||
nua_session_usage_t *ss = nua_dialog_usage_private(sr->sr_usage);
|
||||
nua_dialog_usage_t *du = sr->sr_usage;
|
||||
nua_session_usage_t *ss = nua_dialog_usage_private(du);
|
||||
int early = 0, retval;
|
||||
|
||||
if (sr->sr_status < 200)
|
||||
|
@ -3645,7 +3766,11 @@ int nua_bye_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
|
||||
early = ss->ss_state < nua_callstate_ready;
|
||||
phrase = early ? "Early Session Terminated" : "Session Terminated";
|
||||
|
||||
|
||||
#if 0
|
||||
sr->sr_usage = NULL;
|
||||
#endif
|
||||
|
||||
for (sr0 = nh->nh_ds->ds_sr; sr0; sr0 = sr_next) {
|
||||
sr_next = sr0->sr_next;
|
||||
|
||||
|
@ -3658,16 +3783,22 @@ int nua_bye_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
}
|
||||
nua_server_request_destroy(sr0);
|
||||
}
|
||||
|
||||
sr->sr_phrase = phrase;
|
||||
}
|
||||
|
||||
retval = nua_base_server_report(sr, tags);
|
||||
|
||||
assert(2 <= retval && retval < 4);
|
||||
|
||||
if (ss)
|
||||
signal_call_state_change(nh, NULL, 200,
|
||||
#if 0
|
||||
if (ss) {
|
||||
signal_call_state_change(nh, ss, 200,
|
||||
early ? "Received early BYE" : "Received BYE",
|
||||
nua_callstate_terminated);
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, du);
|
||||
}
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -3799,9 +3930,10 @@ static void signal_call_state_change(nua_handle_t *nh,
|
|||
if (next_state == nua_callstate_init) {
|
||||
if (ss_state < nua_callstate_ready)
|
||||
ss->ss_state = next_state;
|
||||
else
|
||||
/* Do not change state - we are ready, terminating, or terminated */
|
||||
next_state = ss_state;
|
||||
else if (ss->ss_state == nua_callstate_ready)
|
||||
next_state = ss->ss_state;
|
||||
else
|
||||
ss->ss_state = next_state = nua_callstate_terminated;
|
||||
}
|
||||
else if (next_state > ss_state)
|
||||
ss->ss_state = next_state;
|
||||
|
|
|
@ -861,7 +861,7 @@ void nua_stack_shutdown(nua_t *nua)
|
|||
for (nh = nua->nua_handles; nh; nh = nh_next) {
|
||||
nh_next = nh->nh_next;
|
||||
while (nh->nh_ds && nh->nh_ds->ds_usage) {
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, nh->nh_ds->ds_usage);
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, nh->nh_ds->ds_usage, NULL, NULL);
|
||||
}
|
||||
}
|
||||
su_timer_destroy(nua->nua_timer), nua->nua_timer = NULL;
|
||||
|
@ -1867,14 +1867,14 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
|
|||
else
|
||||
terminated = sip_response_terminates_dialog(status, sr->sr_method, NULL);
|
||||
|
||||
if (usage && terminated)
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, usage, NULL, sr);
|
||||
|
||||
nua_server_request_destroy(sr);
|
||||
|
||||
if (!terminated)
|
||||
return 1;
|
||||
|
||||
if (usage)
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, usage);
|
||||
|
||||
if (!initial) {
|
||||
if (terminated > 0)
|
||||
return 2;
|
||||
|
@ -2351,7 +2351,7 @@ msg_t *nua_client_request_template(nua_client_request_t *cr)
|
|||
|
||||
/** Restart the request message.
|
||||
*
|
||||
* A restarted request has not completed successfully.
|
||||
* A restarted request has not been completed successfully.
|
||||
*
|
||||
* @retval 0 if request is pending
|
||||
* @retval >=1 if error event has been sent
|
||||
|
@ -2690,6 +2690,7 @@ int nua_client_response(nua_client_request_t *cr,
|
|||
return 0;
|
||||
|
||||
cr->cr_status = status;
|
||||
cr->cr_phrase = phrase;
|
||||
|
||||
if (status < 200) {
|
||||
/* Xyzzy */
|
||||
|
@ -2735,6 +2736,7 @@ int nua_client_response(nua_client_request_t *cr,
|
|||
cr->cr_methods->crm_preliminary(cr, status, phrase, sip);
|
||||
else
|
||||
nua_base_client_response(cr, status, phrase, sip, NULL);
|
||||
cr->cr_phrase = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2853,6 +2855,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
|
|||
cr->cr_waiting = cr->cr_wait_for_cred = 1;
|
||||
nua_client_report(cr, status, phrase, NULL, orq, NULL);
|
||||
nta_outgoing_destroy(orq);
|
||||
cr->cr_status = 0, cr->cr_phrase = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -2877,6 +2880,7 @@ int nua_base_client_check_restart(nua_client_request_t *cr,
|
|||
cr->cr_waiting = cr->cr_wait_for_timer = 1;
|
||||
nua_client_report(cr, 100, phrase, NULL, orq, NULL);
|
||||
nta_outgoing_destroy(orq);
|
||||
cr->cr_status = 0, cr->cr_phrase = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3065,7 +3069,7 @@ int nua_base_client_response(nua_client_request_t *cr,
|
|||
if (cr->cr_terminated ||
|
||||
(!du->du_ready && status >= 300 && nua_client_is_bound(cr))) {
|
||||
/* Usage has been destroyed */
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, du), cr->cr_usage = NULL;
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, du, cr, NULL), cr->cr_usage = NULL;
|
||||
}
|
||||
else if (cr->cr_graceful) {
|
||||
/* Terminate usage gracefully */
|
||||
|
@ -3078,6 +3082,7 @@ int nua_base_client_response(nua_client_request_t *cr,
|
|||
nua_dialog_remove(nh, nh->nh_ds, NULL), cr->cr_usage = NULL;
|
||||
}
|
||||
|
||||
cr->cr_phrase = NULL;
|
||||
cr->cr_reporting = 0, nh->nh_ds->ds_reporting = 0;
|
||||
|
||||
if (!nua_client_is_queued(cr) && !nua_client_is_bound(cr))
|
||||
|
|
|
@ -74,7 +74,9 @@ static int nua_subscribe_usage_add(nua_handle_t *nh,
|
|||
nua_dialog_usage_t *du);
|
||||
static void nua_subscribe_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du);
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_subscribe_usage_refresh(nua_handle_t *,
|
||||
nua_dialog_state_t *,
|
||||
nua_dialog_usage_t *,
|
||||
|
@ -113,7 +115,9 @@ int nua_subscribe_usage_add(nua_handle_t *nh,
|
|||
static
|
||||
void nua_subscribe_usage_remove(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
nua_dialog_usage_t *du)
|
||||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr)
|
||||
{
|
||||
ds->ds_has_events--;
|
||||
ds->ds_has_subscribes--;
|
||||
|
@ -446,7 +450,7 @@ static void nua_subscribe_usage_refresh(nua_handle_t *nh,
|
|||
NUTAG_SUBSTATE(nua_substate_terminated),
|
||||
SIPTAG_EVENT(du->du_event),
|
||||
TAG_END());
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -469,7 +473,7 @@ static void nua_subscribe_usage_refresh(nua_handle_t *nh,
|
|||
SIPTAG_EVENT(du->du_event),
|
||||
TAG_END());
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
}
|
||||
|
||||
/** Terminate subscription.
|
||||
|
@ -492,7 +496,7 @@ static int nua_subscribe_usage_shutdown(nua_handle_t *nh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
nua_dialog_usage_remove(nh, ds, du);
|
||||
nua_dialog_usage_remove(nh, ds, du, NULL, NULL);
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
@ -874,7 +878,7 @@ static int nua_refer_client_request(nua_client_request_t *cr,
|
|||
}
|
||||
|
||||
if (du0)
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, du0);
|
||||
nua_dialog_usage_remove(nh, nh->nh_ds, du0, NULL, NULL);
|
||||
|
||||
eu = nua_dialog_usage_private(cr->cr_usage = du);
|
||||
eu ->eu_refer = 1;
|
||||
|
|
|
@ -1269,7 +1269,8 @@ tag_typedef_t nutag_autoack = BOOLTAG_TYPEDEF(autoACK);
|
|||
|
||||
/**@def NUTAG_ENABLEINVITE(x)
|
||||
*
|
||||
* Enable incoming INVITE
|
||||
* Enable incoming INVITE.
|
||||
*
|
||||
*
|
||||
* @par Used with
|
||||
* nua_set_params() \n
|
||||
|
@ -2570,7 +2571,8 @@ tag_typedef_t nutag_path_enable = BOOLTAG_TYPEDEF(path_enable);
|
|||
|
||||
/**@def NUTAG_SERVICE_ROUTE_ENABLE(x)
|
||||
*
|
||||
* Use route from @ServiceRoute header in response to REGISTER.
|
||||
* Use route taken from the @ServiceRoute header in the 200 class response
|
||||
* to REGISTER.
|
||||
*
|
||||
* @par Used with
|
||||
* - nua_create(), nua_set_params(), nua_get_params()
|
||||
|
|
Loading…
Reference in New Issue