Mon May 12 18:51:36 EDT 2008 Pekka Pessi <first.last@nokia.com>
* nua: using NUTAG_PROXY() as handle-specific tag Added nua_dialog_update_params() and virtual method usage_update_params() for each dialog usage. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8384 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
052e33d6d2
commit
58312ce2d1
|
@ -1 +1 @@
|
|||
Tue May 13 15:08:14 EDT 2008
|
||||
Tue May 13 15:08:49 EDT 2008
|
||||
|
|
|
@ -30,7 +30,7 @@ nobase_include_sofia_HEADERS = \
|
|||
sofia-sip/nua.h sofia-sip/nua_tag.h
|
||||
|
||||
libnua_la_SOURCES = nua.c nua_stack.h nua_common.c nua_stack.c \
|
||||
nua_extension.c \
|
||||
nua_extension.c nua_types.h \
|
||||
nua_dialog.c nua_dialog.h \
|
||||
outbound.c outbound.h \
|
||||
nua_params.c nua_params.h \
|
||||
|
|
|
@ -468,6 +468,26 @@ void nua_dialog_deinit(nua_owner_t *own,
|
|||
ds->ds_terminating = 0;
|
||||
}
|
||||
|
||||
void nua_dialog_update_params(nua_dialog_state_t *ds,
|
||||
nua_handle_preferences_t const *changed,
|
||||
nua_handle_preferences_t const *params,
|
||||
nua_handle_preferences_t const *defaults)
|
||||
{
|
||||
nua_dialog_usage_t *usage;
|
||||
|
||||
for (usage = ds->ds_usage; usage; usage = usage->du_next) {
|
||||
usage->du_class->usage_update_params(usage, changed, params, defaults);
|
||||
}
|
||||
}
|
||||
|
||||
void nua_base_usage_update_params(nua_dialog_usage_t const *du,
|
||||
nua_handle_preferences_t const *changed,
|
||||
nua_handle_preferences_t const *params,
|
||||
nua_handle_preferences_t const *defaults)
|
||||
{
|
||||
(void)du, (void)changed, (void)params, (void)defaults;
|
||||
}
|
||||
|
||||
/**@internal
|
||||
* Set refresh value suitably.
|
||||
*
|
||||
|
|
|
@ -35,27 +35,12 @@
|
|||
* @date Created: Wed Mar 8 11:38:18 EET 2006 ppessi
|
||||
*/
|
||||
|
||||
#ifndef NUA_OWNER_T
|
||||
#define NUA_OWNER_T struct nua_owner_s
|
||||
#endif
|
||||
typedef NUA_OWNER_T nua_owner_t;
|
||||
#include <nua_types.h>
|
||||
|
||||
#ifndef NTA_H
|
||||
#include <sofia-sip/nta.h>
|
||||
#endif
|
||||
|
||||
typedef struct nua_dialog_state nua_dialog_state_t;
|
||||
typedef struct nua_dialog_usage nua_dialog_usage_t;
|
||||
typedef struct nua_server_request nua_server_request_t;
|
||||
typedef struct nua_client_request nua_client_request_t;
|
||||
typedef struct nua_dialog_peer_info nua_dialog_peer_info_t;
|
||||
|
||||
#ifndef NUA_SAVED_SIGNAL_T
|
||||
#define NUA_SAVED_SIGNAL_T struct nua_saved_signal *
|
||||
#endif
|
||||
|
||||
typedef NUA_SAVED_SIGNAL_T nua_saved_signal_t;
|
||||
|
||||
typedef struct {
|
||||
sip_method_t sm_method;
|
||||
char const *sm_method_name;
|
||||
|
@ -386,6 +371,10 @@ typedef struct {
|
|||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
char const *(*usage_name)(nua_dialog_usage_t const *du);
|
||||
void (*usage_update_params)(nua_dialog_usage_t const *du,
|
||||
nua_handle_preferences_t const *changed,
|
||||
nua_handle_preferences_t const *params,
|
||||
nua_handle_preferences_t const *defaults);
|
||||
void (*usage_peer_info)(nua_dialog_usage_t *du,
|
||||
nua_dialog_state_t const *ds,
|
||||
sip_t const *sip);
|
||||
|
@ -452,6 +441,16 @@ void nua_dialog_usage_remove(nua_owner_t *,
|
|||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
|
||||
void nua_dialog_update_params(nua_dialog_state_t *ds,
|
||||
nua_handle_preferences_t const *changed,
|
||||
nua_handle_preferences_t const *params,
|
||||
nua_handle_preferences_t const *defaults);
|
||||
|
||||
void nua_base_usage_update_params(nua_dialog_usage_t const *du,
|
||||
nua_handle_preferences_t const *changed,
|
||||
nua_handle_preferences_t const *params,
|
||||
nua_handle_preferences_t const *defaults);
|
||||
|
||||
void nua_dialog_deinit(nua_owner_t *own,
|
||||
nua_dialog_state_t *ds);
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ static nua_usage_class const nua_notify_usage[1] = {
|
|||
nua_notify_usage_add,
|
||||
nua_notify_usage_remove,
|
||||
nua_notify_usage_name,
|
||||
nua_base_usage_update_params,
|
||||
NULL,
|
||||
nua_notify_usage_refresh,
|
||||
nua_notify_usage_shutdown,
|
||||
|
|
|
@ -82,17 +82,6 @@ su_inline void nhp_or_set(nua_handle_preferences_t *a,
|
|||
/* Bitwise or of bitfields, casted to unsigned */
|
||||
a->nhp_set_.set_unsigned[0] |= b->nhp_set_.set_unsigned[0];
|
||||
a->nhp_set_.set_unsigned[1] |= b->nhp_set_.set_unsigned[1];
|
||||
|
||||
/*
|
||||
unsigned *ap, const *bp;
|
||||
size_t i;
|
||||
|
||||
ap = a->nhp_set_.set_unsigned;
|
||||
bp = b->nhp_set_.set_unsigned;
|
||||
for (i = 0; i < (sizeof a->nhp_set); i += (sizeof *ap))
|
||||
*ap++ |= *bp++;
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
static int nhp_set_tags(su_home_t *home,
|
||||
|
@ -114,7 +103,6 @@ static int nhp_save_params(nua_handle_t *nh,
|
|||
nua_global_preferences_t *gsrc,
|
||||
nua_handle_preferences_t *src);
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
/* Magical NUTAG_USER_AGENT() - add NHP_USER_AGENT there if it is not there */
|
||||
|
||||
|
@ -310,6 +298,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
|
|||
* NUTAG_ONLY183_100REL() \n
|
||||
* NUTAG_OUTBOUND() \n
|
||||
* NUTAG_PATH_ENABLE() \n
|
||||
* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n
|
||||
* NUTAG_REFER_EXPIRES() \n
|
||||
* NUTAG_REFER_WITH_ID() \n
|
||||
* NUTAG_REGISTRAR() \n
|
||||
|
@ -430,6 +419,7 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
|
|||
* NUTAG_ONLY183_100REL() \n
|
||||
* NUTAG_OUTBOUND() \n
|
||||
* NUTAG_PATH_ENABLE() \n
|
||||
* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) \n
|
||||
* NUTAG_REFER_EXPIRES() \n
|
||||
* NUTAG_REFER_WITH_ID() \n
|
||||
* NUTAG_REGISTRAR() \n
|
||||
|
@ -482,13 +472,15 @@ int nua_stack_set_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
int status;
|
||||
char const *phrase;
|
||||
|
||||
nua_handle_preferences_t tmp[1];
|
||||
int any_changes = 0;
|
||||
|
||||
enter;
|
||||
|
||||
{
|
||||
su_home_t tmphome[1] = { SU_HOME_INIT(tmphome) };
|
||||
nua_handle_preferences_t *nhp = nh->nh_prefs;
|
||||
nua_handle_preferences_t const *dnhp = dnh->nh_prefs;
|
||||
nua_handle_preferences_t tmp[1];
|
||||
nua_global_preferences_t gtmp[1], *ngp = NULL;
|
||||
|
||||
*tmp = *nhp; NHP_UNSET_ALL(tmp);
|
||||
|
@ -521,7 +513,7 @@ int nua_stack_set_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
status = 900, phrase = "Error storing default handle parameters";
|
||||
else if (nhp_set_tags(tmphome, tmp, ngp, tags) < 0)
|
||||
status = 900, phrase = "Error storing parameters";
|
||||
else if (nhp_save_params(nh, tmphome, ngp, tmp) < 0)
|
||||
else if ((any_changes = nhp_save_params(nh, tmphome, ngp, tmp)) < 0)
|
||||
status = 900, phrase = su_strerror(ENOMEM);
|
||||
else
|
||||
status = 200, phrase = "OK", nh->nh_used_ptags = 1;
|
||||
|
@ -562,7 +554,8 @@ int nua_stack_set_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
if (nua_stack_set_smime_params(nua, tags) < 0) {
|
||||
status = 900, phrase = "Error setting S/MIME parameters";
|
||||
}
|
||||
else if (nua->nua_nta && nta_agent_set_params(nua->nua_nta, TAG_NEXT(tags)) < 0) {
|
||||
else if (nua->nua_nta &&
|
||||
nta_agent_set_params(nua->nua_nta, TAG_NEXT(tags)) < 0) {
|
||||
status = 900, phrase = "Error setting NTA parameters";
|
||||
}
|
||||
else {
|
||||
|
@ -581,6 +574,18 @@ int nua_stack_set_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
else {
|
||||
if (e == nua_r_set_params)
|
||||
UA_EVENT2(e, status, phrase);
|
||||
|
||||
if (any_changes) {
|
||||
nua_handle_preferences_t changed[1];
|
||||
|
||||
*changed = *nh->nh_prefs;
|
||||
memcpy(&changed->nhp_set_, &tmp->nhp_set_, sizeof changed->nhp_set_);
|
||||
|
||||
nua_dialog_update_params(nh->nh_ds,
|
||||
changed,
|
||||
nh->nh_prefs,
|
||||
dnh->nh_prefs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -612,11 +617,10 @@ static int nhp_set_tags(su_home_t *home,
|
|||
}
|
||||
|
||||
/* Set copy of string from url to handle pref structure */
|
||||
#define NHP_SET_STR_BY_URL(nhp, name, v) \
|
||||
#define NHP_SET_STR_BY_URL(nhp, type, name, v) \
|
||||
if ((v) != (tag_value_t)-1) { \
|
||||
url_t const *_value = (url_t const *)(v); \
|
||||
char *_new; \
|
||||
_new = url_as_string(home, (void *)_value); \
|
||||
type *_new = (type *)url_as_string(home, (void *)_value); \
|
||||
if (NHP_ISSET(nhp, name)) \
|
||||
su_free(home, (void *)nhp->nhp_##name); \
|
||||
NHP_SET(nhp, name, _new); \
|
||||
|
@ -953,7 +957,7 @@ static int nhp_set_tags(su_home_t *home,
|
|||
}
|
||||
/* NUTAG_REGISTRAR(registrar) */
|
||||
else if (tag == nutag_registrar) {
|
||||
NHP_SET_STR_BY_URL(nhp, registrar, value);
|
||||
NHP_SET_STR_BY_URL(nhp, char, registrar, value);
|
||||
if (NHP_ISSET(nhp, registrar) && !str0cmp(nhp->nhp_registrar, "*"))
|
||||
NHP_SET_STR(nhp, registrar, 0);
|
||||
}
|
||||
|
@ -981,6 +985,10 @@ static int nhp_set_tags(su_home_t *home,
|
|||
else if (tag == nutag_outbound) {
|
||||
NHP_SET_STR(nhp, outbound, value);
|
||||
}
|
||||
/* NUTAG_PROXY() (aka NTATAG_DEFAULT_PROXY()) */
|
||||
else if (tag == ntatag_default_proxy) {
|
||||
NHP_SET_STR_BY_URL(nhp, url_string_t, proxy, value);
|
||||
}
|
||||
/* NUTAG_DETECT_NETWORK_UPDATES(detect_network_updates) */
|
||||
else if (ngp && tag == nutag_detect_network_updates) {
|
||||
int detector = (int)value;
|
||||
|
@ -1070,6 +1078,10 @@ static int nhp_merge_lists(su_home_t *home,
|
|||
}
|
||||
|
||||
/** Save parameters in @a gtmp and @a tmp.
|
||||
*
|
||||
* @retval 1 - parameters were changed
|
||||
* @retval 0 - no changes in parameters
|
||||
* @retval -1 - an error
|
||||
*/
|
||||
static
|
||||
int nhp_save_params(nua_handle_t *nh,
|
||||
|
@ -1132,7 +1144,7 @@ int nhp_save_params(nua_handle_t *nh,
|
|||
|
||||
nh->nh_prefs = dst;
|
||||
|
||||
return 0;
|
||||
return memcmp(dst, old, sizeof *dst) != 0;
|
||||
}
|
||||
|
||||
static int nua_handle_tags_filter(tagi_t const *f, tagi_t const *t);
|
||||
|
@ -1141,21 +1153,6 @@ static int nua_handle_param_filter(tagi_t const *f, tagi_t const *t);
|
|||
/** Save taglist to a handle */
|
||||
int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags)
|
||||
{
|
||||
#if HAVE_OPEN_C
|
||||
/* Nice. An old symbian compiler */
|
||||
tagi_t tagfilter[2];
|
||||
tagi_t paramfilter[2];
|
||||
#else
|
||||
tagi_t const tagfilter[] = {
|
||||
{ TAG_FILTER(nua_handle_tags_filter) },
|
||||
{ TAG_NULL() }
|
||||
};
|
||||
tagi_t const paramfilter[] = {
|
||||
{ TAG_FILTER(nua_handle_param_filter) },
|
||||
{ TAG_NULL() }
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Initialization parameters */
|
||||
url_string_t const *url = NULL;
|
||||
sip_to_t const *p_to = NULL;
|
||||
|
@ -1171,6 +1168,10 @@ int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags)
|
|||
int error;
|
||||
|
||||
#if HAVE_OPEN_C
|
||||
/* Nice. An old symbian compiler */
|
||||
tagi_t tagfilter[2];
|
||||
tagi_t paramfilter[2];
|
||||
|
||||
tagfilter[0].t_tag = tag_filter;
|
||||
tagfilter[0].t_value = tag_filter_v(nua_handle_tags_filter);
|
||||
tagfilter[1].t_tag = (tag_type_t)0;
|
||||
|
@ -1180,6 +1181,16 @@ int nua_handle_save_tags(nua_handle_t *nh, tagi_t *tags)
|
|||
paramfilter[0].t_value = tag_filter_v(nua_handle_param_filter);
|
||||
paramfilter[1].t_tag = (tag_type_t)0;
|
||||
paramfilter[1].t_value = (tag_value_t)0;
|
||||
|
||||
#else
|
||||
tagi_t const tagfilter[] = {
|
||||
{ TAG_FILTER(nua_handle_tags_filter) },
|
||||
{ TAG_NULL() }
|
||||
};
|
||||
tagi_t const paramfilter[] = {
|
||||
{ TAG_FILTER(nua_handle_param_filter) },
|
||||
{ TAG_NULL() }
|
||||
};
|
||||
#endif
|
||||
|
||||
for (t = tags; t; t = tl_next(t)) {
|
||||
|
@ -1525,7 +1536,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
nua_handle_t *dnh = nua->nua_dhandle;
|
||||
nua_global_preferences_t const *ngp = nua->nua_prefs;
|
||||
nua_handle_preferences_t const *nhp = nh->nh_prefs;
|
||||
|
||||
nua_handle_preferences_t const nhp_zero[1] = {{ 0 }};
|
||||
tagi_t *lst;
|
||||
|
||||
int has_from;
|
||||
|
@ -1549,6 +1560,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
|
||||
enter;
|
||||
|
||||
if (nh == dnh)
|
||||
nta_agent_get_params(nua->nua_nta,
|
||||
NTATAG_UDP_MTU_REF(udp_mtu),
|
||||
NTATAG_MAX_PROCEEDING_REF(max_proceeding),
|
||||
|
@ -1597,6 +1609,9 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
? sip_##pref##_make(tmphome, (char *)nhp->nhp_##pref) \
|
||||
: NULL))
|
||||
|
||||
if (nh != dnh && nhp == dnh->nh_prefs)
|
||||
nhp = nhp_zero;
|
||||
|
||||
su_home_auto(tmphome, sizeof(tmphome));
|
||||
|
||||
lst = tl_filtered_tlist
|
||||
|
@ -1669,6 +1684,10 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
TIF(NUTAG_M_FEATURES, m_features),
|
||||
TIF(NUTAG_OUTBOUND, outbound),
|
||||
|
||||
/* Handle-specific proxy */
|
||||
TAG_IF(nh != dnh && nhp->nhp_set.nhb_proxy,
|
||||
NUTAG_PROXY(nhp->nhp_proxy)),
|
||||
|
||||
/* Skip user-agent-level parameters if parameters are for handle only */
|
||||
TAG_IF(nh != dnh, TAG_NEXT(media_params)),
|
||||
|
||||
|
@ -1699,6 +1718,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
|||
NTATAG_SIP_T4(sip_t4),
|
||||
NTATAG_SIP_T1X64(sip_t1x64),
|
||||
NTATAG_DEBUG_DROP_PROB(debug_drop_prob),
|
||||
/* Stack-wide proxy */
|
||||
NTATAG_DEFAULT_PROXY(proxy),
|
||||
NTATAG_ALIASES(aliases),
|
||||
NTATAG_SIPFLAGS(flags),
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
* @date Created: Wed Mar 8 11:38:18 EET 2006 ppessi
|
||||
*/
|
||||
|
||||
#include <nua_types.h>
|
||||
|
||||
/**@internal @brief NUA preferences.
|
||||
*
|
||||
* This structure contains values for various preferences and a separate
|
||||
|
@ -50,7 +52,7 @@
|
|||
*
|
||||
* @see NHP_GET(), NH_PGET(), NHP_ISSET(), NH_PISSET()
|
||||
*/
|
||||
typedef struct nua_handle_preferences
|
||||
struct nua_handle_preferences
|
||||
{
|
||||
unsigned nhp_retry_count; /**< times to retry a request */
|
||||
unsigned nhp_max_subscriptions;
|
||||
|
@ -133,6 +135,9 @@ typedef struct nua_handle_preferences
|
|||
/** Initial route set */
|
||||
sip_route_t *nhp_initial_route;
|
||||
|
||||
/** Next hop URI (used instead of route). */
|
||||
url_string_t *nhp_proxy;
|
||||
|
||||
union { struct {
|
||||
/* A bit for each feature set by application */
|
||||
/* NOTE:
|
||||
|
@ -191,16 +196,17 @@ typedef struct nua_handle_preferences
|
|||
unsigned nhb_outbound:1;
|
||||
unsigned nhb_appl_method:1;
|
||||
unsigned nhb_initial_route:1;
|
||||
unsigned nhb_proxy:1;
|
||||
unsigned :0;
|
||||
} set_bits;
|
||||
unsigned set_unsigned[2];
|
||||
} nhp_set_;
|
||||
} nua_handle_preferences_t;
|
||||
};
|
||||
|
||||
#define nhp_set nhp_set_.set_bits
|
||||
|
||||
/** Global preferences for nua. */
|
||||
typedef struct {
|
||||
struct nua_global_preferences {
|
||||
/** Network detection: NONE, INFORMAL, TRY_FULL */
|
||||
signed int ngp_detect_network_updates:3;
|
||||
/** Pass events during shutdown, too */
|
||||
|
@ -215,7 +221,7 @@ typedef struct {
|
|||
} set_bits;
|
||||
unsigned set_unsigned[2];
|
||||
} ngp_set_;
|
||||
} nua_global_preferences_t;
|
||||
};
|
||||
|
||||
#define ngp_set ngp_set_.set_bits
|
||||
|
||||
|
@ -238,7 +244,7 @@ typedef struct {
|
|||
|
||||
/* Get preference from handle, if set, otherwise from default handle */
|
||||
#define NH_PGET(nh, pref) \
|
||||
NHP_GET((nh)->nh_prefs, (nh)->nh_nua->nua_dhandle->nh_prefs, pref)
|
||||
NHP_GET((nh)->nh_prefs, (nh)->nh_dprefs, pref)
|
||||
|
||||
/* Get preference from handle, if exists and set,
|
||||
otherwise from default handle */
|
||||
|
@ -255,7 +261,7 @@ typedef struct {
|
|||
(NHP_ISSET((nh)->nh_prefs, pref) && \
|
||||
(nh)->nh_nua->nua_dhandle->nh_prefs != (nh)->nh_prefs)
|
||||
|
||||
/* Check if preference has been set by applicationx */
|
||||
/* Check if preference has been set by application */
|
||||
#define NUA_PISSET(nua, nh, pref) \
|
||||
(NHP_ISSET((nua)->nua_dhandle->nh_prefs, pref) || \
|
||||
((nh) && NHP_ISSET((nh)->nh_prefs, pref)))
|
||||
|
|
|
@ -79,6 +79,7 @@ static nua_usage_class const nua_publish_usage[1] = {
|
|||
nua_publish_usage_add,
|
||||
nua_publish_usage_remove,
|
||||
nua_publish_usage_name,
|
||||
nua_base_usage_update_params,
|
||||
NULL,
|
||||
nua_publish_usage_refresh,
|
||||
nua_publish_usage_shutdown,
|
||||
|
|
|
@ -107,6 +107,10 @@ static void nua_register_usage_remove(nua_handle_t *nh,
|
|||
nua_dialog_usage_t *du,
|
||||
nua_client_request_t *cr,
|
||||
nua_server_request_t *sr);
|
||||
static void nua_register_usage_update_params(nua_dialog_usage_t const *du,
|
||||
nua_handle_preferences_t const *,
|
||||
nua_handle_preferences_t const *,
|
||||
nua_handle_preferences_t const *);
|
||||
static void nua_register_usage_peer_info(nua_dialog_usage_t *du,
|
||||
nua_dialog_state_t const *ds,
|
||||
sip_t const *sip);
|
||||
|
@ -169,6 +173,7 @@ nua_usage_class const nua_register_usage[1] = {
|
|||
nua_register_usage_add,
|
||||
nua_register_usage_remove,
|
||||
nua_register_usage_name,
|
||||
nua_register_usage_update_params,
|
||||
nua_register_usage_peer_info,
|
||||
nua_register_usage_refresh,
|
||||
nua_register_usage_shutdown
|
||||
|
@ -672,6 +677,11 @@ static int nua_register_client_init(nua_client_request_t *cr,
|
|||
NH_PGET(nh, instance));
|
||||
if (!nr->nr_ob)
|
||||
return nua_client_return(cr, 900, "Cannot create outbound", msg);
|
||||
|
||||
nua_register_usage_update_params(du,
|
||||
NULL,
|
||||
nh->nh_prefs,
|
||||
nh->nh_dprefs);
|
||||
}
|
||||
|
||||
if (nr->nr_ob) {
|
||||
|
@ -687,13 +697,6 @@ static int nua_register_client_init(nua_client_request_t *cr,
|
|||
unreg = 1; /* All contacts have expires=0 */
|
||||
}
|
||||
|
||||
outbound_set_options(ob,
|
||||
NH_PGET(nh, outbound),
|
||||
NH_PGET(nh, keepalive),
|
||||
NH_PISSET(nh, keepalive_stream)
|
||||
? NH_PGET(nh, keepalive_stream)
|
||||
: NH_PGET(nh, keepalive));
|
||||
|
||||
if (outbound_set_contact(ob, sip->sip_contact, nr->nr_via, unreg) < 0)
|
||||
return nua_client_return(cr, 900, "Cannot set outbound contact", msg);
|
||||
}
|
||||
|
@ -1038,6 +1041,42 @@ void nua_register_connection_closed(tp_stack_t *sip_stack,
|
|||
nua_dialog_usage_set_refresh_range(du, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nua_register_usage_update_params(nua_dialog_usage_t const *du,
|
||||
nua_handle_preferences_t const *changed,
|
||||
nua_handle_preferences_t const *nhp,
|
||||
nua_handle_preferences_t const *dnhp)
|
||||
{
|
||||
nua_registration_t *nr = nua_dialog_usage_private(du);
|
||||
outbound_t *ob = nr->nr_ob;
|
||||
|
||||
if (!ob)
|
||||
return;
|
||||
|
||||
if (!changed ||
|
||||
NHP_ISSET(changed, outbound) ||
|
||||
NHP_ISSET(changed, keepalive) ||
|
||||
NHP_ISSET(changed, keepalive_stream)) {
|
||||
char const *outbound =
|
||||
NHP_ISSET(nhp, outbound) ? nhp->nhp_outbound
|
||||
: dnhp->nhp_outbound;
|
||||
unsigned keepalive =
|
||||
NHP_ISSET(nhp, keepalive) ? nhp->nhp_keepalive
|
||||
: dnhp->nhp_keepalive;
|
||||
unsigned keepalive_stream =
|
||||
NHP_ISSET(nhp, keepalive_stream) ? nhp->nhp_keepalive_stream
|
||||
: NHP_ISSET(dnhp, keepalive_stream) ? nhp->nhp_keepalive_stream
|
||||
: keepalive;
|
||||
|
||||
outbound_set_options(ob, outbound, keepalive, keepalive_stream);
|
||||
}
|
||||
|
||||
if (!changed || NHP_ISSET(changed, proxy)) {
|
||||
if (NHP_ISSET(nhp, proxy))
|
||||
outbound_set_proxy(ob, nhp->nhp_proxy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void nua_register_usage_refresh(nua_handle_t *nh,
|
||||
nua_dialog_state_t *ds,
|
||||
|
|
|
@ -207,6 +207,7 @@ static nua_usage_class const nua_session_usage[1] = {
|
|||
nua_session_usage_add,
|
||||
nua_session_usage_remove,
|
||||
nua_session_usage_name,
|
||||
nua_base_usage_update_params,
|
||||
NULL,
|
||||
nua_session_usage_refresh,
|
||||
nua_session_usage_shutdown
|
||||
|
@ -335,9 +336,6 @@ void nua_session_usage_destroy(nua_handle_t *nh,
|
|||
/* ======================================================================== */
|
||||
/* INVITE and call (session) processing */
|
||||
|
||||
int nua_stack_prack(nua_t *nua, nua_handle_t *nh, nua_event_t e,
|
||||
tagi_t const *tags);
|
||||
|
||||
static int session_timer_is_supported(struct session_timer const *t);
|
||||
|
||||
static void session_timer_preferences(struct session_timer *t,
|
||||
|
@ -1206,6 +1204,8 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
|
|||
sip_authorization_t *wa;
|
||||
sip_proxy_authorization_t *pa;
|
||||
sip_cseq_t *cseq;
|
||||
int proxy_is_set;
|
||||
url_string_t *proxy;
|
||||
nta_outgoing_t *ack;
|
||||
int status = 200;
|
||||
char const *phrase = "OK", *reason = NULL;
|
||||
|
@ -1314,9 +1314,14 @@ int nua_invite_client_ack(nua_client_request_t *cr, tagi_t const *tags)
|
|||
}
|
||||
}
|
||||
|
||||
proxy_is_set = NH_PISSET(nh, proxy);
|
||||
proxy = NH_PGET(nh, proxy);
|
||||
|
||||
if ((ack = nta_outgoing_mcreate(nh->nh_nua->nua_nta, NULL, NULL, NULL,
|
||||
msg,
|
||||
NTATAG_ACK_BRANCH(invite_branch),
|
||||
TAG_IF(proxy_is_set,
|
||||
NTATAG_DEFAULT_PROXY(proxy)),
|
||||
SIPTAG_END(),
|
||||
TAG_NEXT(tags)))) {
|
||||
/* TR engine keeps this around for T2 so it catches all 2XX retransmissions */
|
||||
|
|
|
@ -2633,6 +2633,8 @@ int nua_base_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip,
|
|||
tagi_t const *tags)
|
||||
{
|
||||
nua_handle_t *nh = cr->cr_owner;
|
||||
int proxy_is_set = NH_PISSET(nh, proxy);
|
||||
url_string_t * proxy = NH_PGET(nh, proxy);
|
||||
|
||||
if (nh->nh_auth) {
|
||||
if (cr->cr_challenged ||
|
||||
|
@ -2648,6 +2650,8 @@ int nua_base_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip,
|
|||
nua_client_orq_response, cr,
|
||||
NULL,
|
||||
msg,
|
||||
TAG_IF(proxy_is_set,
|
||||
NTATAG_DEFAULT_PROXY(proxy)),
|
||||
TAG_NEXT(tags));
|
||||
|
||||
return cr->cr_orq ? 0 : -1;
|
||||
|
|
|
@ -154,6 +154,7 @@ struct nua_handle_s
|
|||
nua_handle_t *nh_identity; /**< Identity */
|
||||
|
||||
nua_handle_preferences_t *nh_prefs; /**< Preferences */
|
||||
#define nh_dprefs nh_nua->nua_dhandle->nh_prefs
|
||||
|
||||
/* Handle type is determined by special event and flags. */
|
||||
nua_event_t nh_special; /**< Special event */
|
||||
|
|
|
@ -91,6 +91,7 @@ static nua_usage_class const nua_subscribe_usage[1] = {
|
|||
nua_subscribe_usage_add,
|
||||
nua_subscribe_usage_remove,
|
||||
nua_subscribe_usage_name,
|
||||
nua_base_usage_update_params,
|
||||
NULL,
|
||||
nua_subscribe_usage_refresh,
|
||||
nua_subscribe_usage_shutdown
|
||||
|
|
|
@ -104,7 +104,7 @@ struct outbound {
|
|||
unsigned ob_registering:1;
|
||||
/** 2XX response to REGISTER containg ob_rcontact has been received */
|
||||
unsigned ob_registered:1;
|
||||
/**The registration has been validated:
|
||||
/** The registration has been validated:
|
||||
* We have successfully sent OPTIONS to ourselves.
|
||||
*/
|
||||
unsigned ob_validated:1;
|
||||
|
@ -113,8 +113,11 @@ struct outbound {
|
|||
* up if OPTIONS probe fails.
|
||||
*/
|
||||
unsigned ob_once_validated:1;
|
||||
|
||||
unsigned ob_proxy_override:1; /**< Override stack default proxy */
|
||||
unsigned :0;
|
||||
|
||||
url_string_t *ob_proxy; /**< Outbound-specific proxy */
|
||||
char const *ob_instance; /**< Our instance ID */
|
||||
int32_t ob_reg_id; /**< Flow-id */
|
||||
sip_contact_t *ob_rcontact; /**< Our contact */
|
||||
|
@ -209,10 +212,11 @@ outbound_new(outbound_owner_t *owner,
|
|||
ob->ob_nta = agent;
|
||||
|
||||
if (instance)
|
||||
ob->ob_instance = su_strcat_all(ob->ob_home, "+sip.instance=\"<", instance, ">\"", NULL);
|
||||
ob->ob_instance =
|
||||
su_sprintf(ob->ob_home, "+sip.instance=\"<%s>\"", instance);
|
||||
ob->ob_reg_id = 0;
|
||||
|
||||
/* Generate a cookie (used as Call-ID) for us */
|
||||
/* Generate a random cookie (used as Call-ID) for us */
|
||||
su_md5_init(md5);
|
||||
su_guid_generate(guid);
|
||||
if (instance)
|
||||
|
@ -246,16 +250,23 @@ void outbound_unref(outbound_t *ob)
|
|||
|
||||
/** Set various outbound and nat-traversal related options. */
|
||||
int outbound_set_options(outbound_t *ob,
|
||||
char const *options,
|
||||
char const *_options,
|
||||
unsigned interval,
|
||||
unsigned stream_interval)
|
||||
{
|
||||
struct outbound_prefs prefs[1] = {{ 0 }};
|
||||
char const *s;
|
||||
char *s, *options = su_strdup(NULL, _options);
|
||||
int invalid;
|
||||
|
||||
prefs->interval = interval;
|
||||
prefs->stream_interval = stream_interval;
|
||||
|
||||
#define MATCH(v) (len == sizeof(#v) - 1 && strncasecmp(#v, s, len) == 0)
|
||||
|
||||
if (options) {
|
||||
for (s = options; s[0]; s++) if (s[0] == '-') s[0] = '_';
|
||||
}
|
||||
|
||||
prefs->gruuize = 1;
|
||||
prefs->outbound = 0;
|
||||
prefs->natify = 1;
|
||||
|
@ -263,17 +274,11 @@ int outbound_set_options(outbound_t *ob,
|
|||
prefs->validate = 1;
|
||||
prefs->use_rport = 1;
|
||||
|
||||
#define MATCH(v) (len == sizeof(#v) - 1 && strncasecmp(#v, s, len) == 0)
|
||||
|
||||
for (s = options; s && s[0]; ) {
|
||||
size_t len = span_token(s);
|
||||
int value = 1;
|
||||
|
||||
if (len > 3 && strncasecmp(s, "no-", 3) == 0)
|
||||
value = 0, s += 3, len -= 3;
|
||||
else if (len > 4 && strncasecmp(s, "not-", 4) == 0)
|
||||
value = 0, s += 4, len -= 4;
|
||||
else if (len > 3 && strncasecmp(s, "no_", 3) == 0)
|
||||
if (len > 3 && strncasecmp(s, "no_", 3) == 0)
|
||||
value = 0, s += 3, len -= 3;
|
||||
else if (len > 4 && strncasecmp(s, "not_", 4) == 0)
|
||||
value = 0, s += 4, len -= 4;
|
||||
|
@ -284,14 +289,12 @@ int outbound_set_options(outbound_t *ob,
|
|||
else if (MATCH(outbound)) prefs->outbound = value;
|
||||
else if (MATCH(natify)) prefs->natify = value;
|
||||
else if (MATCH(validate)) prefs->validate = value;
|
||||
else if (MATCH(options-keepalive)) prefs->okeepalive = value;
|
||||
else if (MATCH(options_keepalive)) prefs->okeepalive = value;
|
||||
else if (MATCH(use-connect)) prefs->use_connect = value;
|
||||
else if (MATCH(use_connect)) prefs->use_connect = value;
|
||||
else if (MATCH(use-rport) || MATCH(use_rport)) prefs->use_rport = value;
|
||||
else if (MATCH(use-socks) || MATCH(use_socks)) prefs->use_socks = value;
|
||||
else if (MATCH(use-upnp) || MATCH(use_upnp)) prefs->use_upnp = value;
|
||||
else if (MATCH(use-stun) || MATCH(use_stun)) prefs->use_stun = value;
|
||||
else if (MATCH(use_rport)) prefs->use_rport = value;
|
||||
else if (MATCH(use_socks)) prefs->use_socks = value;
|
||||
else if (MATCH(use_upnp)) prefs->use_upnp = value;
|
||||
else if (MATCH(use_stun)) prefs->use_stun = value;
|
||||
else
|
||||
SU_DEBUG_1(("outbound(%p): unknown option \"%.*s\"\n",
|
||||
(void *)ob->ob_owner, (int)len, s));
|
||||
|
@ -303,7 +306,10 @@ int outbound_set_options(outbound_t *ob,
|
|||
s += len;
|
||||
}
|
||||
|
||||
if (s && s[0]) {
|
||||
invalid = s && s[0];
|
||||
su_free(NULL, options);
|
||||
|
||||
if (invalid) {
|
||||
SU_DEBUG_1(("outbound(%p): invalid options \"%s\"\n",
|
||||
(void *)ob->ob_owner, options));
|
||||
return -1;
|
||||
|
@ -326,6 +332,25 @@ int outbound_set_options(outbound_t *ob,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Override stack default proxy for outbound */
|
||||
int outbound_set_proxy(outbound_t *ob,
|
||||
url_string_t *proxy)
|
||||
{
|
||||
url_string_t *new_proxy = NULL, *old_proxy = ob->ob_proxy;
|
||||
|
||||
if (proxy)
|
||||
new_proxy = (url_string_t *)url_as_string(ob->ob_home, proxy->us_url);
|
||||
|
||||
if (proxy == NULL || new_proxy != NULL) {
|
||||
ob->ob_proxy_override = 1;
|
||||
ob->ob_proxy = new_proxy;
|
||||
su_free(ob->ob_home, old_proxy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/** Obtain contacts for REGISTER */
|
||||
|
@ -784,6 +809,8 @@ static int keepalive_options(outbound_t *ob)
|
|||
ob,
|
||||
NULL,
|
||||
req,
|
||||
TAG_IF(ob->ob_proxy_override,
|
||||
NTATAG_DEFAULT_PROXY(ob->ob_proxy)),
|
||||
TAG_END());
|
||||
|
||||
if (!ob->ob_keepalive.orq)
|
||||
|
@ -949,6 +976,8 @@ static int keepalive_options_with_registration_probe(outbound_t *ob)
|
|||
ob,
|
||||
NULL,
|
||||
req,
|
||||
TAG_IF(ob->ob_proxy_override,
|
||||
NTATAG_DEFAULT_PROXY(ob->ob_proxy)),
|
||||
SIPTAG_SUBJECT_STR("REGISTRATION PROBE"),
|
||||
/* NONE is used to remove
|
||||
Max-Forwards: 0 found in ordinary keepalives */
|
||||
|
|
|
@ -70,6 +70,9 @@ int outbound_set_options(outbound_t *ob,
|
|||
unsigned dgram_interval,
|
||||
unsigned stream_interval);
|
||||
|
||||
int outbound_set_proxy(outbound_t *ob,
|
||||
url_string_t *proxy);
|
||||
|
||||
int outbound_get_contacts(outbound_t *ob,
|
||||
sip_contact_t **return_current_contact,
|
||||
sip_contact_t **return_previous_contact);
|
||||
|
|
Loading…
Reference in New Issue