freeswitch/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c

1735 lines
52 KiB
C
Raw Normal View History

/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2006 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@CFILE nua_register.c
* @brief REGISTER and registrations
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Wed Mar 8 11:48:49 EET 2006 ppessi
*/
#include "config.h"
#include <sofia-sip/string0.h>
#include <sofia-sip/su_strlst.h>
#include <sofia-sip/token64.h>
#include <sofia-sip/su_tagarg.h>
#include <sofia-sip/su_tag_inline.h>
#include <sofia-sip/bnf.h>
#include <sofia-sip/sip_protos.h>
#include <sofia-sip/sip_util.h>
#include <sofia-sip/sip_status.h>
#include <sofia-sip/msg_parser.h>
#include "nua_stack.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#if !HAVE_STRCASESTR
char *strcasestr(char const *haystack, char const *needle);
#endif
/* ====================================================================== */
/* Helper macros and functions for handling #nua_handle_preferences_t. */
#define NHP_IS_ANY_SET(nhp) nhp_is_any_set((nhp))
/** Check if any preference is set in @a nhp. */
su_inline int nhp_is_any_set(nua_handle_preferences_t const *nhp)
{
char nhp_zero[sizeof nhp->nhp_set] = { 0 };
return memcmp(&nhp->nhp_set, nhp_zero, sizeof nhp->nhp_set) != 0;
}
/** Copy set parameters from @a b to @a a.
*
* If preference is set in @a b, mark it set also in @a a.
*/
su_inline void nhp_or_set(nua_handle_preferences_t *a,
nua_handle_preferences_t const *b)
{
memcpy(a, b, offsetof(nua_handle_preferences_t, nhp_set));
/* 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];
}
static int nhp_set_tags(su_home_t *home,
nua_handle_preferences_t *nhp,
nua_global_preferences_t *ngp,
tagi_t const *tags);
static int nhp_merge_lists(su_home_t *home,
msg_hclass_t *hc,
msg_list_t **return_new_list,
msg_list_t const *old_list,
int already_set,
int already_parsed,
int always_merge,
tag_value_t value);
static int nhp_save_params(nua_handle_t *nh,
su_home_t *tmphome,
nua_global_preferences_t *gsrc,
nua_handle_preferences_t *src);
/* ====================================================================== */
/* Magical NUTAG_USER_AGENT() - add NHP_USER_AGENT there if it is not there */
#define NHP_USER_AGENT PACKAGE_NAME "/" PACKAGE_VERSION
static int already_contains_package_name(char const *s)
{
char const pn[] = " " PACKAGE_NAME "/";
size_t pnlen = strlen(pn + 1);
return strncasecmp(s, pn + 1, pnlen) == 0 || strcasestr(s, pn);
}
/* ====================================================================== */
/* Stack and handle parameters */
static int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags);
/** @internal Methods allowed by default. */
static char const nua_allow_str[] =
"INVITE, ACK, BYE, CANCEL, OPTIONS, PRACK, "
"MESSAGE, SUBSCRIBE, NOTIFY, REFER, UPDATE";
/** @internal Set default parameters */
int nua_stack_set_defaults(nua_handle_t *nh,
nua_handle_preferences_t *nhp)
{
su_home_t *home = (su_home_t *)nh;
/* Set some defaults */
NHP_SET(nhp, retry_count, 3);
NHP_SET(nhp, max_subscriptions, 20);
NHP_SET(nhp, media_enable, 1);
NHP_SET(nhp, invite_enable, 1);
NHP_SET(nhp, auto_alert, 0);
NHP_SET(nhp, early_media, 0);
NHP_SET(nhp, only183_100rel, 0);
NHP_SET(nhp, auto_answer, 0);
NHP_SET(nhp, auto_ack, 1);
NHP_SET(nhp, invite_timeout, 120);
nhp->nhp_session_timer = 1800;
nhp->nhp_refresher = nua_no_refresher;
NHP_SET(nhp, min_se, 120);
NHP_SET(nhp, update_refresh, 0);
NHP_SET(nhp, message_enable, 1);
NHP_SET(nhp, win_messenger_enable, 0);
if (getenv("PIMIW_HACK") != 0)
NHP_SET(nhp, message_auto_respond, 1);
NHP_SET(nhp, media_features, 0);
NHP_SET(nhp, callee_caps, 0);
NHP_SET(nhp, service_route_enable, 1);
NHP_SET(nhp, path_enable, 1);
NHP_SET(nhp, refer_expires, 300);
NHP_SET(nhp, refer_with_id, 1);
NHP_SET(nhp, substate, nua_substate_active);
NHP_SET(nhp, sub_expires, 3600);
NHP_SET(nhp, allow, sip_allow_make(home, nua_allow_str));
NHP_SET(nhp, supported, sip_supported_make(home, "timer, 100rel"));
NHP_SET(nhp, user_agent, su_strdup(home, NHP_USER_AGENT));
NHP_SET(nhp, outbound, su_strdup(home, "natify"));
NHP_SET(nhp, keepalive, 120000);
NHP_SET(nhp, appl_method,
sip_allow_make(home, "INVITE, REGISTER, PUBLISH, SUBSCRIBE"));
if (!nhp->nhp_allow ||
!nhp->nhp_supported ||
!nhp->nhp_user_agent ||
!nhp->nhp_outbound)
return -1;
return 0;
}
/** @internal Set the default from field */
int nua_stack_set_from(nua_t *nua, int initial, tagi_t const *tags)
{
sip_from_t const *from = NONE;
char const *str = NONE;
sip_from_t *f = NULL, f0[1];
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
int set;
tl_gets(tags,
/* By nua_stack_set_from() */
SIPTAG_FROM_REF(from),
SIPTAG_FROM_STR_REF(str),
TAG_END());
if (!initial && from == NONE && str == NONE)
return 0;
sip_from_init(f0);
if (from && from != NONE) {
f0->a_display = from->a_display;
*f0->a_url = *from->a_url;
f = sip_from_dup(nua->nua_home, f0);
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
set = 1;
}
else if (str && str != NONE) {
f = sip_from_make(nua->nua_home, str);
if (f)
*f0 = *f, f = f0, f->a_params = NULL;
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
set = 1;
}
else {
sip_contact_t const *m;
m = nua_stack_get_contact(nua->nua_registrations);
if (m) {
f0->a_display = m->m_display;
*f0->a_url = *m->m_url;
f = sip_from_dup(nua->nua_home, f0);
}
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
set = 0;
}
if (!f)
return -1;
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
nua->nua_from_is_set = set;
*nua->nua_from = *f;
return 0;
}
/** @internal Initialize instance ID. */
int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags)
{
nua_handle_preferences_t *nhp = nh->nh_prefs;
char const *instance = NONE;
tl_gets(tags, NUTAG_INSTANCE_REF(instance), TAG_END());
if (instance != NONE) {
NHP_SET(nhp, instance, su_strdup(nh->nh_home, instance));
if (instance && !nhp->nhp_instance)
return -1;
}
return 0;
}
/**@fn void nua_set_params(nua_t *nua, tag_type_t tag, tag_value_t value, ...)
*
* Set @nua parameters, shared by all handles.
*
* @param nua Pointer to NUA stack object
* @param tag, value, ... List of tagged parameters
*
* @return
* nothing
*
* @par Related tags:
* NUTAG_ALLOW(), SIPTAG_ALLOW(), and SIPTAG_ALLOW_STR() \n
* NUTAG_ALLOW_EVENTS(), SIPTAG_ALLOW_EVENTS(), and
* SIPTAG_ALLOW_EVENTS_STR() \n
* NUTAG_AUTOACK() \n
* NUTAG_AUTOALERT() \n
* NUTAG_AUTOANSWER() \n
* NUTAG_CALLEE_CAPS() \n
* NUTAG_DETECT_NETWORK_UPDATES() \n
* NUTAG_EARLY_ANSWER() \n
* NUTAG_EARLY_MEDIA() \n
* NUTAG_ENABLEINVITE() \n
* NUTAG_ENABLEMESSAGE() \n
* NUTAG_ENABLEMESSENGER() \n
* NUTAG_INITIAL_ROUTE() \n
* NUTAG_INITIAL_ROUTE_STR() \n
* NUTAG_INSTANCE() \n
* NUTAG_INVITE_TIMER() \n
* NUTAG_KEEPALIVE() \n
* NUTAG_KEEPALIVE_STREAM() \n
* NUTAG_MAX_SUBSCRIPTIONS() \n
* NUTAG_MEDIA_ENABLE() \n
* NUTAG_MEDIA_FEATURES() \n
* NUTAG_MIN_SE() \n
* NUTAG_M_DISPLAY() \n
* NUTAG_M_FEATURES() \n
* NUTAG_M_PARAMS() \n
* NUTAG_M_USERNAME() \n
* 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
* NUTAG_RETRY_COUNT() \n
* NUTAG_SERVICE_ROUTE_ENABLE() \n
* NUTAG_SESSION_REFRESHER() \n
* NUTAG_SESSION_TIMER() \n
* NUTAG_SMIME_ENABLE() \n
* NUTAG_SMIME_KEY_ENCRYPTION() \n
* NUTAG_SMIME_MESSAGE_DIGEST() \n
* NUTAG_SMIME_MESSAGE_ENCRYPTION() \n
* NUTAG_SMIME_OPT() \n
* NUTAG_SMIME_PROTECTION_MODE() \n
* NUTAG_SMIME_SIGNATURE() \n
* NUTAG_SOA_NAME() \n
* NUTAG_SUBSTATE() \n
* NUTAG_SUB_EXPIRES() \n
* NUTAG_SUPPORTED(), SIPTAG_SUPPORTED(), and SIPTAG_SUPPORTED_STR() \n
* NUTAG_UPDATE_REFRESH() \n
* NUTAG_USER_AGENT(), SIPTAG_USER_AGENT() and SIPTAG_USER_AGENT_STR() \n
* SIPTAG_ORGANIZATION() and SIPTAG_ORGANIZATION_STR() \n
*
* nua_set_params() also accepts any soa tags, defined in
* <sofia-sip/soa_tag.h>, and nta tags, defined in <sofia-sip/nta_tag.h>.
*
* @par Events:
* #nua_r_set_params
*
* @par SIP Header as NUA Parameters
* The @nua parameters include SIP headers @Allow, @Supported, @Organization,
* @UserAgent and @From. They are included in most of the SIP messages sent
* by @nua. They are set in the same way as the tagged arguments are
* used to populate a SIP message.
* @par
* When multiple tags for the same header are specified, the behaviour
* depends on the header type. If only a single header field can be included
* in a SIP message, the latest non-NULL value is used, e.g., @Organization.
* However, if the SIP header can consist of multiple lines or header fields
* separated by comma, in this case, @Allow and @Supported, all the tagged
* values are concatenated.
* @par
* However, if the tag value is #SIP_NONE (-1 casted as a void pointer), the
* values from previous tags are ignored.
*
* For example, the nua_set_params() call like this:
* @code
* nua_set_params(nua,
* SIPTAG_USER_AGENT_STR("tester/1.0"),
* SIPTAG_ALLOW_STR("INVITE,CANCEL,BYE,ACK"),
* SIPTAG_ORGANIZATION(NULL),
* SIPTAG_USER_AGENT(NULL),
* SIPTAG_ALLOW(SIP_NONE),
* TAG_END());
* @endcode
* will leave @Allow and @Organization headers empty. The @UserAgent header
* will contain value "tester/1.0".
* @code
* nua_set_params(nua,
* SIPTAG_ORGANIZATION_STR("Malevolent Microwavers"),
* SIPTAG_ALLOW_STR("OPTIONS"),
* SIPTAG_ALLOW(SIP_NONE),
* SIPTAG_ORGANIZATION_STR("The Phone Company"),
* SIPTAG_ALLOW_STR("SUBSCRIBE"),
* SIPTAG_ALLOW(NULL),
* SIPTAG_ORGANIZATION_STR(NULL),
* TAG_END());
* @endcode
* sets the header @Allow with value <code>SUBSCRIBE</code> and the
* header @Organization will have value <code>The Phone Company</code>.
*
*/
/**@fn void nua_set_hparams(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...);
*
* Set the handle-specific parameters.
*
* The handle-specific parameters override default or global parameters set
* by nua_set_params(). The handle-specific parameters are set by several
* other operations: nua_invite(), nua_respond(), nua_ack(),
* nua_prack(), nua_update(), nua_info(), nua_bye(), nua_options(),
* nua_message(), nua_register(), nua_publish(), nua_refer(),
* nua_subscribe(), nua_notify(), nua_refer(), and nua_notifier().
*
* @param nh Pointer to a NUA handle
* @param tag, value, ... List of tagged parameters
*
* @return
* nothing
*
* @par Tags Used to Set Handle-Specific Parameters:
* NUTAG_ALLOW(), SIPTAG_ALLOW(), and SIPTAG_ALLOW_STR() \n
* NUTAG_ALLOW_EVENTS(), SIPTAG_ALLOW_EVENTS(), and
* SIPTAG_ALLOW_EVENTS_STR() \n
* NUTAG_AUTH_CACHE() \n
* NUTAG_AUTOACK() \n
* NUTAG_AUTOALERT() \n
* NUTAG_AUTOANSWER() \n
* NUTAG_CALLEE_CAPS() \n
* NUTAG_EARLY_ANSWER() \n
* NUTAG_EARLY_MEDIA() \n
* NUTAG_ENABLEINVITE() \n
* NUTAG_ENABLEMESSAGE() \n
* NUTAG_ENABLEMESSENGER() \n
* NUTAG_INITIAL_ROUTE() \n
* NUTAG_INITIAL_ROUTE_STR() \n
* NUTAG_INSTANCE() \n
* NUTAG_INVITE_TIMER() \n
* NUTAG_KEEPALIVE() \n
* NUTAG_KEEPALIVE_STREAM() \n
* NUTAG_MAX_SUBSCRIPTIONS() \n
* NUTAG_MEDIA_ENABLE() \n
* NUTAG_MEDIA_FEATURES() \n
* NUTAG_MIN_SE() \n
* NUTAG_M_DISPLAY() \n
* NUTAG_M_FEATURES() \n
* NUTAG_M_PARAMS() \n
* NUTAG_M_USERNAME() \n
* 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
* NUTAG_RETRY_COUNT() \n
* NUTAG_SERVICE_ROUTE_ENABLE() \n
* NUTAG_SESSION_REFRESHER() \n
* NUTAG_SESSION_TIMER() \n
* NUTAG_SOA_NAME() \n
* NUTAG_SUBSTATE() \n
* NUTAG_SUB_EXPIRES() \n
* NUTAG_SUPPORTED(), SIPTAG_SUPPORTED(), and SIPTAG_SUPPORTED_STR() \n
* NUTAG_UPDATE_REFRESH() \n
* NUTAG_USER_AGENT(), SIPTAG_USER_AGENT() and SIPTAG_USER_AGENT_STR() \n
* SIPTAG_ORGANIZATION() and SIPTAG_ORGANIZATION_STR() \n
* Any soa tags are also considered as handle-specific parameters. They are
* defined in <sofia-sip/soa_tag.h>.
*
* The global parameters that can not be set by nua_set_hparams() include
* NUTAG_DETECT_NETWORK_UPDATES(), NUTAG_SMIME_* tags, and all NTA tags.
*
* @par Events:
* #nua_r_set_params
*/
/** @NUA_EVENT nua_r_set_params
*
* Response to nua_set_params() or nua_set_hparams().
*
* @param status 200 when successful, error code otherwise
* @param phrase a short textual description of @a status code
* @param nh NULL when responding to nua_set_params(),
* operation handle when responding to nua_set_hparams()
* @param hmagic NULL when responding to nua_set_params(),
* application contact associated with the operation handle
* when responding to nua_set_hparams()
* @param sip NULL
* @param tags None
*
* @sa nua_set_params(), nua_set_hparams(),
* #nua_r_get_params, nua_get_params(), nua_get_hparams()
*
* @END_NUA_EVENT
*/
int nua_stack_set_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
tagi_t const *tags)
{
nua_handle_t *dnh = nua->nua_dhandle;
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_global_preferences_t gtmp[1], *ngp = NULL;
*tmp = *nhp; NHP_UNSET_ALL(tmp);
/*
* Supported features, allowed methods and events are merged
* with previous or default settings.
*
* Here we just copy pointers from default settings. However when saving
* settings we have to be extra careful so that we
* 1) zero the pointers if the setting has not been modified
* 2) do not free pointer if the setting has been modified
* See NHP_ZAP_OVERRIDEN() below for gorier details.
*/
if (!NHP_ISSET(nhp, supported))
tmp->nhp_supported = dnhp->nhp_supported;
if (!NHP_ISSET(nhp, allow))
tmp->nhp_allow = dnhp->nhp_allow;
if (!NHP_ISSET(nhp, allow_events))
tmp->nhp_allow_events = dnhp->nhp_allow_events;
if (!NHP_ISSET(nhp, appl_method))
tmp->nhp_appl_method = dnhp->nhp_appl_method;
if (nh == dnh) /* nua_set_params() call, save stack-wide params, too */
ngp = gtmp, *gtmp = *nua->nua_prefs;
/* Set and save parameters to tmp */
if (!nh->nh_used_ptags &&
nhp_set_tags(tmphome, tmp, NULL, nh->nh_ptags) < 0)
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 ((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;
su_home_deinit(tmphome);
}
if (status == 200) {
nua_handle_preferences_t const *nhp = nh->nh_prefs;
nua_handle_preferences_t const *dnhp = dnh->nh_prefs;
if (!nh->nh_soa && NHP_GET(nhp, dnhp, media_enable)) {
/* Create soa when needed */
char const *soa_name = NHP_GET(nhp, dnhp, soa_name);
if (dnh->nh_soa)
nh->nh_soa = soa_clone(dnh->nh_soa, nua->nua_root, nh);
else
nh->nh_soa = soa_create(soa_name, nua->nua_root, nh);
if (!nh->nh_soa)
status = 900, phrase = "Error Creating SOA Object";
else if (soa_set_params(nh->nh_soa, TAG_NEXT(nh->nh_ptags)) < 0)
status = 900, phrase = "Error Setting SOA Parameters";
}
else if (nh->nh_soa && !NHP_GET(nhp, dnhp, media_enable)) {
/* ... destroy soa when not needed */
soa_destroy(nh->nh_soa), nh->nh_soa = NULL;
}
if (status == 200 && tags && nh->nh_soa &&
soa_set_params(nh->nh_soa, TAG_NEXT(tags)) < 0)
status = 900, phrase = "Error Setting SOA Parameters";
}
if (status == 200 && nh == dnh) {
/* Set stack-specific things below */
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) {
status = 900, phrase = "Error setting NTA parameters";
}
else {
nua_stack_set_from(nua, 0, tags);
if (nua->nua_prefs->ngp_detect_network_updates)
nua_stack_launch_network_change_detector(nua);
}
}
if (status != 200) {
if (e == nua_i_none)
SU_DEBUG_1(("nua_set_params(): failed: %s\n", phrase));
return UA_EVENT2(e, status, phrase), -1;
}
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;
}
}
/** Parse parameters from tags to @a nhp or @a ngp.
*
* @param home allocate new values from @a home
* @param nhp structure to store handle preferences
* @param ngp structure to store global preferences
* @param tags list of tags to parse
*/
static int nhp_set_tags(su_home_t *home,
nua_handle_preferences_t *nhp,
nua_global_preferences_t *ngp,
tagi_t const *tags)
{
/* Set copy of string to handle pref structure */
#define NHP_SET_STR(nhp, name, v) \
if ((v) != (tag_value_t)0) { \
char const *_value = (char const *)v; \
char *_new = _value ? su_strdup(home, _value) : NULL; \
if (NHP_ISSET(nhp, name)) \
su_free(home, (void *)nhp->nhp_##name); \
NHP_SET(nhp, name, _new); \
if (_new == NULL && _value != NULL) \
return -1; \
}
/* Set copy of string from url to handle pref structure */
#define NHP_SET_STR_BY_URL(nhp, type, name, v) \
if ((v) != (tag_value_t)-1) { \
url_t const *_value = (url_t const *)(v); \
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); \
if (_new == NULL && _value != NULL) \
return -1; \
}
/* Set copy of header to handle pref structure */
#define NHP_SET_HEADER(nhp, name, hdr, v) \
if ((v) != 0) { \
sip_##hdr##_t const *_value = (sip_##hdr##_t const *)(v); \
sip_##hdr##_t *_new = NULL; \
if (_value != SIP_NONE) \
_new = sip_##name##_dup(home, _value); \
if (NHP_ISSET(nhp, name)) \
msg_header_free_all(home, (void *)nhp->nhp_##name); \
NHP_SET(nhp, name, _new); \
if (_new == NULL && _value != SIP_NONE) \
return -1; \
}
/* Set header made of string to handle pref structure */
#define NHP_SET_HEADER_STR(nhp, name, hdr, v) \
if ((v) != 0) { \
char const *_value = (char const *)(v); \
sip_##hdr##_t *_new = NULL; \
if (_value != SIP_NONE) \
_new = sip_##name##_make(home, _value); \
if (NHP_ISSET(nhp, name)) \
msg_header_free_all(home, (void *)nhp->nhp_##name); \
NHP_SET(nhp, name, _new); \
if (_new == NULL && _value != SIP_NONE) \
return -1; \
}
/* Append copy of header to handle pref structure */
#define NHP_APPEND_HEADER(nhp, name, hdr, is_str, next, v) \
{ \
sip_##hdr##_t const *_value = (sip_##hdr##_t const *)(v); \
char const *_str = (char const *)(v); \
sip_##hdr##_t *_new = NULL; \
sip_##hdr##_t **_end = &nhp->nhp_##name; \
if (_value != SIP_NONE && _value != NULL) { \
_new = (is_str) \
? sip_##hdr##_make(home, _str) \
: sip_##hdr##_dup(home, _value); \
if (_new == NULL) return -1; \
} \
if (NHP_ISSET(nhp, name)) \
while(*_end) \
_end = next(*_end); \
nhp->nhp_set.nhb_##name = 1; \
*_end = _new; \
}
/* Set copy of string from header to handle pref structure */
#define NHP_SET_STR_BY_HEADER(nhp, name, v) \
if ((v) != 0) { \
sip_##name##_t const *_value = (sip_##name##_t const *)(v); \
char *_new = NULL; \
if (_value != SIP_NONE) \
_new = sip_header_as_string(home, (void *)_value); \
if (NHP_ISSET(nhp, name)) \
su_free(home, (void *)nhp->nhp_##name); \
NHP_SET(nhp, name, _new); \
if (_new == NULL && _value != SIP_NONE) \
return -1; \
}
tagi_t const *t;
for (t = tags; t; t = tl_next(t)) {
tag_type_t tag = t->t_tag;
tag_value_t value = t->t_value;
if (tag == NULL)
break;
/* NUTAG_RETRY_COUNT(retry_count) */
else if (tag == nutag_retry_count) {
NHP_SET(nhp, retry_count, (unsigned)value);
}
/* NUTAG_MAX_SUBSCRIPTIONS(max_subscriptions) */
else if (tag == nutag_max_subscriptions) {
NHP_SET(nhp, max_subscriptions, (unsigned)value);
}
/* NUTAG_SOA_NAME(soa_name) */
else if (tag == nutag_soa_name) {
NHP_SET_STR(nhp, soa_name, value);
}
/* NUTAG_MEDIA_ENABLE(media_enable) */
else if (tag == nutag_media_enable) {
NHP_SET(nhp, media_enable, value != 0);
}
/* NUTAG_ENABLEINVITE(invite_enable) */
else if (tag == nutag_enableinvite) {
NHP_SET(nhp, invite_enable, value != 0);
}
/* NUTAG_AUTOALERT(auto_alert) */
else if (tag == nutag_autoalert) {
NHP_SET(nhp, auto_alert, value != 0);
}
/* NUTAG_EARLY_ANSWER(early_answer) */
else if (tag == nutag_early_answer) {
NHP_SET(nhp, early_answer, value != 0);
}
/* NUTAG_EARLY_MEDIA(early_media) */
else if (tag == nutag_early_media) {
NHP_SET(nhp, early_media, value != 0);
}
/* NUTAG_ONLY183_100REL(only183_100rel) */
else if (tag == nutag_only183_100rel) {
NHP_SET(nhp, only183_100rel, value != 0);
}
/* NUTAG_AUTOANSWER(auto_answer) */
else if (tag == nutag_autoanswer) {
NHP_SET(nhp, auto_answer, value != 0);
}
/* NUTAG_AUTOACK(auto_ack) */
else if (tag == nutag_autoack) {
NHP_SET(nhp, auto_ack, value != 0);
}
/* NUTAG_INVITE_TIMER(invite_timeout) */
else if (tag == nutag_invite_timer) {
NHP_SET(nhp, invite_timeout, (unsigned)value);
}
/* NUTAG_SESSION_TIMER(session_timer) */
else if (tag == nutag_session_timer) {
NHP_SET(nhp, session_timer, (unsigned)value);
}
/* NUTAG_MIN_SE(min_se) */
else if (tag == nutag_min_se) {
NHP_SET(nhp, min_se, (unsigned)value);
}
/* NUTAG_SESSION_REFRESHER(refresher) */
else if (tag == nutag_session_refresher) {
int refresher = value;
if (refresher >= nua_remote_refresher)
refresher = nua_remote_refresher;
else if (refresher <= nua_no_refresher)
refresher = nua_no_refresher;
NHP_SET(nhp, refresher, refresher);
}
/* NUTAG_UPDATE_REFRESH(update_refresh) */
else if (tag == nutag_update_refresh) {
NHP_SET(nhp, update_refresh, value != 0);
}
/* NUTAG_ENABLEMESSAGE(message_enable) */
else if (tag == nutag_enablemessage) {
NHP_SET(nhp, message_enable, value != 0);
}
/* NUTAG_ENABLEMESSENGER(win_messenger_enable) */
else if (tag == nutag_enablemessenger) {
NHP_SET(nhp, win_messenger_enable, value != 0);
}
/* NUTAG_CALLEE_CAPS(callee_caps) */
else if (tag == nutag_callee_caps) {
NHP_SET(nhp, callee_caps, value != 0);
}
/* NUTAG_MEDIA_FEATURES(media_features) */
else if (tag == nutag_media_features) {
NHP_SET(nhp, media_features, value != 0);
}
/* NUTAG_SERVICE_ROUTE_ENABLE(service_route_enable) */
else if (tag == nutag_service_route_enable) {
NHP_SET(nhp, service_route_enable, value != 0);
}
/* NUTAG_PATH_ENABLE(path_enable) */
else if (tag == nutag_path_enable) {
NHP_SET(nhp, path_enable, value != 0);
}
/* NUTAG_AUTH_CACHE(auth_cache) */
else if (tag == nutag_auth_cache) {
if (value >= 0 && value < (tag_value_t)_nua_auth_cache_invalid)
NHP_SET(nhp, auth_cache, (int)value);
}
/* NUTAG_REFER_EXPIRES(refer_expires) */
else if (tag == nutag_refer_expires) {
NHP_SET(nhp, refer_expires, value);
}
/* NUTAG_REFER_WITH_ID(refer_with_id) */
else if (tag == nutag_refer_with_id) {
NHP_SET(nhp, refer_with_id, value != 0);
}
/* NUTAG_SUBSTATE(substate) */
else if (tag == nutag_substate) {
NHP_SET(nhp, substate, (int)value);
}
/* NUTAG_SUB_EXPIRES(sub_expires) */
else if (tag == nutag_sub_expires) {
NHP_SET(nhp, sub_expires, value);
}
/* NUTAG_KEEPALIVE(keepalive) */
else if (tag == nutag_keepalive) {
NHP_SET(nhp, keepalive, (unsigned)value);
}
/* NUTAG_KEEPALIVE_STREAM(keepalive_stream) */
else if (tag == nutag_keepalive_stream) {
NHP_SET(nhp, keepalive_stream, (unsigned)value);
}
/* NUTAG_SUPPORTED(feature) */
/* SIPTAG_SUPPORTED_STR(supported_str) */
/* SIPTAG_SUPPORTED(supported) */
else if (tag == nutag_supported ||
tag == siptag_supported ||
tag == siptag_supported_str) {
int ok;
sip_supported_t *supported = NULL;
ok = nhp_merge_lists(home,
sip_supported_class, &supported, nhp->nhp_supported,
NHP_ISSET(nhp, supported), /* already set by tags */
tag == siptag_supported, /* dup it, don't make */
tag == nutag_supported, /* merge with old value */
t->t_value);
if (ok < 0)
return -1;
else if (ok)
NHP_SET(nhp, supported, supported);
}
/* NUTAG_ALLOW(allowing) */
/* SIPTAG_ALLOW_STR(allow_str) */
/* SIPTAG_ALLOW(allow) */
else if (tag == nutag_allow ||
tag == siptag_allow_str ||
tag == siptag_allow) {
int ok;
msg_list_t *allow = NULL;
ok = nhp_merge_lists(home,
sip_allow_class,
&allow,
(msg_list_t const *)nhp->nhp_allow,
NHP_ISSET(nhp, allow), /* already set by tags */
tag == siptag_allow, /* dup it, don't make */
tag == nutag_allow, /* merge with old value */
t->t_value);
if (ok < 0)
return -1;
else if (ok)
NHP_SET(nhp, allow, (sip_allow_t *)allow);
}
/* NUTAG_ALLOW_EVENTS(allow_events) */
/* SIPTAG_ALLOW_EVENTS_STR(allow_events) */
/* SIPTAG_ALLOW_EVENTS(allow_events) */
else if (tag == nutag_allow_events ||
tag == siptag_allow_events_str ||
tag == siptag_allow_events) {
int ok;
sip_allow_events_t *allow_events = NULL;
ok = nhp_merge_lists(home,
sip_allow_events_class,
&allow_events,
nhp->nhp_allow_events,
NHP_ISSET(nhp, allow_events), /* already set */
tag == siptag_allow_events, /* dup it, don't make */
tag == nutag_allow_events, /* merge with old value */
t->t_value);
if (ok < 0)
return -1;
else if (ok)
NHP_SET(nhp, allow_events, allow_events);
}
/* NUTAG_APPL_METHOD(appl_method) */
else if (tag == nutag_appl_method) {
if (t->t_value == 0) {
NHP_SET(nhp, appl_method, NULL);
}
else {
int ok;
msg_list_t *appl_method = NULL;
ok = nhp_merge_lists(home,
sip_allow_class,
&appl_method,
(msg_list_t const *)nhp->nhp_appl_method,
/* already set by tags? */
NHP_ISSET(nhp, appl_method),
0, /* dup it, don't make */
1, /* merge with old value */
t->t_value);
if (ok < 0)
return -1;
else if (ok)
NHP_SET(nhp, appl_method, (sip_allow_t *)appl_method);
}
}
else if (tag == nutag_initial_route ||
tag == nutag_initial_route_str) {
#define next_route(r) (&(r)->r_next)
NHP_APPEND_HEADER(nhp, initial_route, route,
(tag == nutag_initial_route_str),
next_route,
t->t_value);
sip_route_fix(nhp->nhp_initial_route);
}
/* SIPTAG_USER_AGENT(user_agent) */
else if (tag == siptag_user_agent) {
NHP_SET_STR_BY_HEADER(nhp, user_agent, value);
}
/* SIPTAG_USER_AGENT_STR(user_agent_str) */
else if (tag == siptag_user_agent_str && value != 0) {
if (value == -1)
value = 0;
NHP_SET_STR(nhp, user_agent, value);
}
/* NUTAG_USER_AGENT(ua_name) */
else if (tag == nutag_user_agent) {
/* Add contents of NUTAG_USER_AGENT() to our distribution name */
char const *str = (void *)value, *ua;
if (str && !already_contains_package_name(str))
ua = su_sprintf(home, "%s %s", str, NHP_USER_AGENT);
else if (str)
ua = su_strdup(home, str);
else
ua = su_strdup(home, NHP_USER_AGENT);
NHP_SET(nhp, user_agent, ua);
}
/* SIPTAG_ORGANIZATION(organization) */
else if (tag == siptag_organization) {
NHP_SET_STR_BY_HEADER(nhp, organization, value);
}
/* SIPTAG_ORGANIZATION_STR(organization_str) */
else if (tag == siptag_organization_str) {
if (value == -1)
value = 0;
NHP_SET_STR(nhp, organization, value);
}
/* NUTAG_REGISTRAR(registrar) */
else if (tag == nutag_registrar) {
NHP_SET_STR_BY_URL(nhp, char, registrar, value);
if (NHP_ISSET(nhp, registrar) && !str0cmp(nhp->nhp_registrar, "*"))
NHP_SET_STR(nhp, registrar, 0);
}
/* NUTAG_INSTANCE(instance) */
else if (tag == nutag_instance) {
NHP_SET_STR(nhp, instance, value);
}
/* NUTAG_M_DISPLAY(m_display) */
else if (tag == nutag_m_display) {
NHP_SET_STR(nhp, m_display, value);
}
/* NUTAG_M_USERNAME(m_username) */
else if (tag == nutag_m_username) {
NHP_SET_STR(nhp, m_username, value);
}
/* NUTAG_M_PARAMS(m_params) */
else if (tag == nutag_m_params) {
NHP_SET_STR(nhp, m_params, value);
}
/* NUTAG_M_FEATURES(m_features) */
else if (tag == nutag_m_features) {
NHP_SET_STR(nhp, m_features, value);
}
/* NUTAG_OUTBOUND(outbound) */
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;
if (detector < NUA_NW_DETECT_NOTHING)
detector = NUA_NW_DETECT_NOTHING;
else if (detector > NUA_NW_DETECT_TRY_FULL)
detector = NUA_NW_DETECT_TRY_FULL;
ngp->ngp_detect_network_updates = detector;
ngp->ngp_set.ngp_detect_network_updates = 1;
}
/* NUTAG_SHUTDOWN_EVENTS() */
else if (ngp && tag == nutag_shutdown_events) {
ngp->ngp_shutdown_events = value != 0;
ngp->ngp_set.ngp_shutdown_events = 1;
}
}
return 0;
}
/** Merge (when needed) new values with old values. */
static int nhp_merge_lists(su_home_t *home,
msg_hclass_t *hc,
msg_list_t **return_new_list,
msg_list_t const *old_list,
int already_set,
int already_parsed,
int always_merge,
tag_value_t value)
{
msg_list_t *list, *elems;
if (value == -1) {
*return_new_list = NULL;
return 1;
}
if (value == 0) {
if (!already_set && !always_merge) {
*return_new_list = NULL;
return 1;
}
return 0;
}
if (already_parsed)
elems = (void *)msg_header_dup_as(home, hc, (msg_header_t *)value);
else
elems = (void *)msg_header_make(home, hc, (char const *)value);
if (!elems)
return -1;
list = (msg_list_t *)old_list;
if (!already_set) {
if (always_merge && list) {
list = (void *)msg_header_dup_as(home, hc, (void *)old_list);
if (!list)
return -1;
}
else
list = NULL;
}
if (!list) {
*return_new_list = elems;
return 1;
}
/* Add contents to the new list to the old list */
if (msg_params_join(home, (msg_param_t **)&list->k_items, elems->k_items,
2 /* prune */, 0 /* don't dup */) < 0)
return -1;
*return_new_list =
(msg_list_t *)msg_header_dup_as(home, hc, (msg_header_t *)list);
if (!*return_new_list)
return -1;
msg_header_free(home, (msg_header_t *)list);
msg_header_free(home, (msg_header_t *)elems);
return 1;
}
/** 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,
su_home_t *tmphome,
nua_global_preferences_t *gsrc,
nua_handle_preferences_t *src)
{
su_home_t *home = nh->nh_home;
nua_t *nua = nh->nh_nua;
nua_handle_t *dnh = nua->nua_dhandle;
nua_handle_preferences_t *dst = nh->nh_prefs, old[1];
if (gsrc) {
*nua->nua_prefs = *gsrc; /* No pointers this far */
}
if (!NHP_IS_ANY_SET(src))
return 0;
if (nh == dnh || nh->nh_prefs != dnh->nh_prefs) {
dst = nh->nh_prefs, *old = *dst;
}
else {
dst = su_zalloc(home, sizeof *dst), memset(old, 0, sizeof *old);
if (!dst)
return -1;
}
/* Move allocations from tmphome to home */
su_home_move(nh->nh_home, tmphome);
/* Copy parameters that are set from src to dst */
nhp_or_set(dst, src);
/* Handle pointer items. Free changed ones and zap unset ones. */
/* Note that pointer items where !NHP_ISSET(old, pref) are not freed
(because they were just on loan from the default preference set) */
#define NHP_ZAP_OVERRIDEN(old, dst, free, pref) \
(((NHP_ISSET(old, pref) && \
(old)->nhp_##pref && (old)->nhp_##pref != (dst)->nhp_##pref) \
? (free)(home, (void *)(old)->nhp_##pref) : (void)0), \
(void)(!(dst)->nhp_set.nhb_##pref ? (dst)->nhp_##pref = NULL : NULL))
NHP_ZAP_OVERRIDEN(old, dst, su_free, soa_name);
NHP_ZAP_OVERRIDEN(old, dst, su_free, registrar);
NHP_ZAP_OVERRIDEN(old, dst, msg_header_free, allow);
NHP_ZAP_OVERRIDEN(old, dst, msg_header_free, supported);
NHP_ZAP_OVERRIDEN(old, dst, msg_header_free, allow_events);
NHP_ZAP_OVERRIDEN(old, dst, su_free, user_agent);
NHP_ZAP_OVERRIDEN(old, dst, su_free, organization);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_display);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_username);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_params);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_features);
NHP_ZAP_OVERRIDEN(old, dst, su_free, instance);
NHP_ZAP_OVERRIDEN(old, dst, su_free, outbound);
NHP_ZAP_OVERRIDEN(old, dst, msg_header_free, appl_method);
NHP_ZAP_OVERRIDEN(old, dst, msg_header_free, initial_route);
nh->nh_prefs = dst;
return memcmp(dst, old, sizeof *dst) != 0;
}
static int nua_handle_tags_filter(tagi_t const *f, tagi_t const *t);
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)
{
/* Initialization parameters */
url_string_t const *url = NULL;
sip_to_t const *p_to = NULL;
char const *to_str = NULL;
sip_from_t const *p_from = NULL;
char const *from_str = NULL;
nua_handle_t *identity = NULL;
tagi_t const *t;
su_home_t tmphome[SU_HOME_AUTO_SIZE(1024)];
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;
tagfilter[1].t_value = (tag_value_t)0;
paramfilter[0].t_tag = tag_filter;
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)) {
if (t->t_tag == NULL)
break;
/* SIPTAG_FROM_REF(p_from) */
else if (t->t_tag == siptag_from) {
p_from = (sip_from_t *)t->t_value, from_str = NULL;
}
/* SIPTAG_FROM_STR_REF(from_str) */
else if (t->t_tag == siptag_from_str) {
from_str = (char const *)t->t_value, p_from = NULL;
}
/* SIPTAG_TO_REF(p_to) */
else if (t->t_tag == siptag_to) {
p_to = (sip_to_t *)t->t_value, to_str = NULL;
}
/* SIPTAG_TO_STR_REF(to_str) */
else if (t->t_tag == siptag_to_str) {
to_str = (char const *)t->t_value, p_to = NULL;
}
/* NUTAG_IDENTITY_REF(identity) */
else if (t->t_tag == nutag_identity) {
identity = (nua_handle_t *)t->t_value;
}
/* NUTAG_URL_REF(url) */
else if (t->t_tag == nutag_url) {
url = (url_string_t *)t->t_value;
}
/* NUTAG_SIPS_URL_REF(url) */
Merge up to the most recent sofia-sip darcs tree. Includes the following patches from darcs: Tue Aug 21 09:38:59 EDT 2007 Pekka.Pessi@nokia.com * tport_type_udp.c: checking error while checking that MSG_TRUNC works. Shall I pull this patch? (1/43) [ynWvpxqadjk], or ? for help: y Tue Aug 21 10:49:33 EDT 2007 Pekka.Pessi@nokia.com * nua_params.c: NUTAG_SIPS_URL() now sets the handle target, too. Problem reported by Jari Tenhunen. Shall I pull this patch? (2/43) [ynWvpxqadjk], or ? for help: y Thu Aug 23 11:22:42 EDT 2007 Pekka.Pessi@nokia.com * nta.c: do not destroy INVITE transaction if it has been CANCELed Handle gracefully cases where the INVITE transaction is destroyed immediately after canceling it. The old behaviour was to left it up to the application to ACK the final response returned to INVITE. Thanks for Fabio Margarido for reporting this problem. Shall I pull this patch? (3/43) [ynWvpxqadjk], or ? for help: y Thu Aug 23 13:02:01 EDT 2007 Pekka.Pessi@nokia.com * test_soa.c: added test with user SDP containing already rejected media Shall I pull this patch? (4/43) [ynWvpxqadjk], or ? for help: y Fri Aug 24 09:41:20 EDT 2007 Pekka.Pessi@nokia.com * nta: added option for processing orphan responses matching with a dialog The orphan responses matching with the dialog can now be processed by the response callback.The dialog leg can be created with NTATAG_RESPONSE_CALLBACK() or a response callback can be later bound to the leg with nta_leg_bind_response(). This is practically useful only with 200 OK responses to the INVITE that are retransmitted by the UAS. By default, the retransmission are catched by the ACK transaction (which then retransmits the ACK request message). However, after ACK transaction times out, the retransmitted 200 OK indicates most probably that the ACK request messages do not reach UAS. Partially fixes the sf.net bug #1750691 reported by Mikhail Zabaluev. Shall I pull this patch? (5/43) [ynWvpxqadjk], or ? for help: y Fri Aug 24 09:41:20 EDT 2007 Pekka.Pessi@nokia.com UNDO: nta: added option for processing orphan responses matching with a dialog The orphan responses matching with the dialog can now be processed by the response callback.The dialog leg can be created with NTATAG_RESPONSE_CALLBACK() or a response callback can be later bound to the leg with nta_leg_bind_response(). This is practically useful only with 200 OK responses to the INVITE that are retransmitted by the UAS. By default, the retransmission are catched by the ACK transaction (which then retransmits the ACK request message). However, after ACK transaction times out, the retransmitted 200 OK indicates most probably that the ACK request messages do not reach UAS. Partially fixes the sf.net bug #1750691 reported by Mikhail Zabaluev. Shall I pull this patch? (6/43) [ynWvpxqadjk], or ? for help: y Thu Aug 30 07:00:10 EDT 2007 Pekka.Pessi@nokia.com * nta.c: disabled nta_msg_ackbye(). Fix for sf.net bug #1750691 Thanks for Mikhail Zabaluev for reporting this bug. Shall I pull this patch? (7/43) [ynWvpxqadjk], or ? for help: y Thu Aug 30 06:54:38 EDT 2007 Pekka.Pessi@nokia.com * test_nua: added test for sf.net bug #1750691 Shall I pull this patch? (8/43) [ynWvpxqadjk], or ? for help: y Thu Aug 30 07:03:45 EDT 2007 Pekka.Pessi@nokia.com * test_nua: added test for nua_bye() sending CANCEL Shall I pull this patch? (9/43) [ynWvpxqadjk], or ? for help: y Fri Aug 31 12:08:09 EDT 2007 Pekka.Pessi@nokia.com * url.c: fixed escaping of '/' %2F, ';' %3B and '=' %3D in URL path/params Thanks for Fabio Margarido for reporting this bug. Shall I pull this patch? (10/43) [ynWvpxqadjk], or ? for help: y Mon Sep 3 10:14:55 EDT 2007 Pekka.Pessi@nokia.com * url.c: do not un-escape %40 in URI parameters. Do not unescape %2C, %3B, %3D, or %40 in URI parameters, nor %2C, %2F, %3B, %3D, or %40 in URI path. The @ sign can be ambiguous in the SIP URL, e.g., <sip:test.info;p=value@test.com> can be parsed in two ways: 1) username contains test.info;param=value and host part has test.com 2) empty username, host part test.info, URI parameter p=value@test.com Previously Sofia URL parser converted escaped '@' at signs (%40) in the URI parameters to the unescaped form. The resulting URI could be ambiguous and sometimes fail the syntax check if there was no '@' sign before the unescaped one. Thanks for Jan van den Bosch and Mikhail Zabaluev for reporting this bug. Shall I pull this patch? (11/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 04:59:57 EDT 2007 Pekka.Pessi@nokia.com * tport.c: fixed indenting, logging Shall I pull this patch? (12/43) [ynWvpxqadjk], or ? for help: y Fri Jul 13 12:47:33 EDT 2007 Pekka.Pessi@nokia.com * nua/test_proxy.h, nua/test_proxy.c: added support for multiple domains Each domain has its own registrar and authentication module. Shall I pull this patch? (13/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 11:19:33 EDT 2007 Pekka.Pessi@nokia.com * test_ops.c: added timestamp to event logging Shall I pull this patch? (14/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 11:20:12 EDT 2007 Pekka.Pessi@nokia.com * test_nua: fixed timing problems in testing. Shall I pull this patch? (15/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 11:31:04 EDT 2007 Pekka.Pessi@nokia.com * test_ops.c: reduce su_root_step() delay to 0.1 seconds Shall I pull this patch? (16/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 11:31:22 EDT 2007 Pekka.Pessi@nokia.com * test_register.c: fixed timing problem Shall I pull this patch? (17/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 17:03:46 EDT 2007 Pekka.Pessi@nokia.com * test_100rel.c: fixed timing problems resulting in events being reordered Shall I pull this patch? (18/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:40:53 EDT 2007 Pekka.Pessi@nokia.com * nua (test_init.c, test_register.c): using test_proxy domains Shall I pull this patch? (19/43) [ynWvpxqadjk], or ? for help: y Thu Aug 23 12:12:32 EDT 2007 Pekka.Pessi@nokia.com * test_soa.c: added cleanup code Shall I pull this patch? (20/43) [ynWvpxqadjk], or ? for help: y Fri Aug 24 09:35:35 EDT 2007 Pekka.Pessi@nokia.com * nta.c: increase lifetime of ACK transaction from T4 to T1 x 64 nta.c creates a ACK transaction in order to restransmit ACK requests when ever a retransmitted 2XX response to INVITE is received. The UAS retransmits the 2XX responses for 64 x T1 (32 second by default). Partially fixes the sf.net bug #1750691 reported by Mikhail Zabaluev. Shall I pull this patch? (21/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 10:21:04 EDT 2007 Pekka.Pessi@nokia.com * Makefile.am: generating libsofia-sip-ua/docs/Doxyfile.rfc before making manpages Shall I pull this patch? (22/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:05:33 EDT 2007 Pekka.Pessi@nokia.com * sofia-sip/tport_tag.h: added TPTAG_KEEPALIVE(), TPTAG_PINGPONG(), TPTAG_PONG2PING() Shall I pull this patch? (23/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:09:06 EDT 2007 Pekka.Pessi@nokia.com * tport: added ping-pong keepalive on TCP. replaced single tick with connection-specific timer Now detecting closed connections on TLS, too. Added tests for idle timeout, receive timeout, ping-pong timeout. Shall I pull this patch? (24/43) [ynWvpxqadjk], or ? for help: y Fri Jul 6 10:19:32 EDT 2007 Pekka.Pessi@nokia.com * nta.c: added nta_incoming_received() Shall I pull this patch? (25/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 11:29:56 EDT 2007 Pekka.Pessi@nokia.com * nua_session.c: delay transition to ready when O/A is incomplete Delay sending ACK and subsequent transition of call to the ready state when the 200 OK response to the INVITE is received if the SDP Offer/Answer exchange using UPDATE/PRACK was still incomplete. Previously, if the O/A using UPDATE or PRACK was incomplete and an 200 OK was received, the call setup logic regarded this as a fatal error and terminated the call. Thanks for Mike Jerris for detecting and reporting this bug. Shall I pull this patch? (26/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:22:46 EDT 2007 Pekka.Pessi@nokia.com * test_call_reject.c: testing Retry-After Shall I pull this patch? (27/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:42:51 EDT 2007 Pekka.Pessi@nokia.com * test_nua: using rudimentary outbound support in B's proxy. Shall I pull this patch? (28/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:48:33 EDT 2007 Pekka.Pessi@nokia.com * nua_register.c: added some logging to nua_register_connection_closed() Shall I pull this patch? (29/43) [ynWvpxqadjk], or ? for help: y Wed Jul 25 12:43:57 EDT 2007 Pekka.Pessi@nokia.com * test_nua: using AUTHTAG_MAX_NCOUNT(1) for Mr. C C is now challenged every time. Shall I pull this patch? (30/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 11:05:19 EDT 2007 Pekka.Pessi@nokia.com * nua/test_100rel.c: fixed timing problem re response to PRACK and ACK Shall I pull this patch? (31/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 06:02:50 EDT 2007 Mikhail Zabaluev <mikhail.zabaluev@nokia.com> * DIST_SUBDIRS must include everything unconditionally Shall I pull this patch? (32/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 13:53:04 EDT 2007 Pekka.Pessi@nokia.com * test_soa.c: silenced warnings Shall I pull this patch? (33/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 16:59:48 EDT 2007 Pekka.Pessi@nokia.com * nua: refactored dialog refresh code Shall I pull this patch? (34/43) [ynWvpxqadjk], or ? for help: y Mon Jul 23 16:59:48 EDT 2007 Pekka.Pessi@nokia.com UNDO: nua: refactored dialog refresh code Shall I pull this patch? (35/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 12:01:25 EDT 2007 Pekka.Pessi@nokia.com * nua_dialog.[hc]: renamed functions setting refresh interval Shall I pull this patch? (36/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 12:15:03 EDT 2007 Pekka.Pessi@nokia.com * nua_dialog.[hc], nua_stack.c: added nua_dialog_repeat_shutdown() Shall I pull this patch? (37/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 12:19:20 EDT 2007 Pekka.Pessi@nokia.com * nua_dialog.h: renamed nua_remote_t as nua_dialog_peer_info_t Shall I pull this patch? (38/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 12:23:04 EDT 2007 Pekka.Pessi@nokia.com * nua_stack.c: added timer to client request in order to implement Retry-After Shall I pull this patch? (39/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 12:33:53 EDT 2007 Pekka.Pessi@nokia.com * nua: added backpointers to nua_dialog_usage_t and nua_dialog_state_t Shall I pull this patch? (40/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 13:56:48 EDT 2007 Pekka.Pessi@nokia.com * test_nua.c: abort() in timeout alarm function if -a is given Shall I pull this patch? (41/43) [ynWvpxqadjk], or ? for help: y Thu Sep 6 17:13:18 EDT 2007 Pekka.Pessi@nokia.com * nua_subnotref.c: include SIPTAG_EVENT() in the nua_i_notify tag list Shall I pull this patch? (42/43) [ynWvpxqadjk], or ? for help: y Mon Sep 10 12:27:53 EDT 2007 Pekka.Pessi@nokia.com * nua: save Contact from target refresh request or response. Save the Contact header which the application has added to the target refresh requests or responses and use the saved contact in subsequent target refresh requests or responses. Previously the application had no way of specifying the Contact included in the automatic responses to target refresh requests. Thanks for Anthony Minessale for reporting this problem. Shall I pull this patch? (43/43) [ynWvpxqadjk], or ? for help: y git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5692 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-09-10 20:45:25 +00:00
else if (t->t_tag == nutag_sips_url) {
url = (url_string_t *)t->t_value;
}
}
su_home_auto(tmphome, sizeof tmphome);
if (p_from)
;
else if (from_str)
p_from = sip_from_make(tmphome, from_str);
else
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
p_from = SIP_NONE;
if (p_to)
;
else if (to_str)
p_to = sip_to_make(tmphome, to_str);
else if (url)
p_to = sip_to_create(tmphome, url),
p_to ? sip_aor_strip((url_t*)p_to->a_url) : 0;
else
p_to = SIP_NONE;
if (p_to == NULL || p_from == NULL) {
su_home_deinit(tmphome);
return -1;
}
nh->nh_tags =
tl_filtered_tlist(nh->nh_home, tagfilter,
TAG_IF(p_from != SIP_NONE, SIPTAG_FROM(p_from)),
TAG_IF(p_from != SIP_NONE, TAG_FILTER(nua_handle_tags_filter)),
TAG_IF(p_to != SIP_NONE, SIPTAG_TO(p_to)),
TAG_IF(p_to != SIP_NONE, TAG_FILTER(nua_handle_tags_filter)),
TAG_NEXT(tags));
nh->nh_ptags =
tl_filtered_tlist(nh->nh_home, paramfilter, TAG_NEXT(tags));
error = nh->nh_tags == NULL || nh->nh_ptags == NULL;
if (!error)
tl_gets(nh->nh_tags, /* These does not change while nh lives */
SIPTAG_FROM_REF(nh->nh_ds->ds_local),
SIPTAG_TO_REF(nh->nh_ds->ds_remote),
TAG_END());
if (nh->nh_ptags && nh->nh_ptags->t_tag == NULL)
su_free(nh->nh_home, nh->nh_ptags), nh->nh_ptags = NULL;
if (identity)
nh->nh_identity = nua_handle_ref(identity);
su_home_deinit(tmphome);
return -error;
}
/** Filter tags used for settings. */
static int nua_handle_param_filter(tagi_t const *f, tagi_t const *t)
{
char const *ns;
if (!t || !t->t_tag)
return 0;
if (t->t_tag == nutag_url ||
t->t_tag == nutag_sips_url ||
t->t_tag == nutag_identity)
return 0;
ns = t->t_tag->tt_ns;
if (!ns)
return 0;
return strcmp(ns, "nua") == 0 || strcmp(ns, "soa") == 0;
}
/** Filter tags stored permanently as taglist. */
static int nua_handle_tags_filter(tagi_t const *f, tagi_t const *t)
{
tag_type_t tag;
if (!t || !t->t_tag)
return 0;
tag = t->t_tag;
if (tag == tag_filter)
return 0;
/* Accept @From or @To only when they are followed by
TAG_FILTER(nua_handle_tags_filter) */
if (tag == siptag_from || tag == siptag_to) {
t = tl_next(t);
return t && t->t_tag == tag_filter &&
t->t_value == (tag_value_t)nua_handle_tags_filter;
}
if (tag == nutag_identity)
return 0;
if (tag == siptag_from_str)
return 0;
if (tag == siptag_to_str)
return 0;
/** Ignore @CSeq, @RSeq, @RAck, @Timestamp, and @ContentLength */
if (tag == siptag_cseq || tag == siptag_cseq_str)
return 0;
if (tag == siptag_rseq || tag == siptag_rseq_str)
return 0;
if (tag == siptag_rack || tag == siptag_rack_str)
return 0;
if (tag == siptag_timestamp || tag == siptag_timestamp_str)
return 0;
if (tag == siptag_content_length || tag == siptag_content_length_str)
return 0;
return ! nua_handle_param_filter(f, t);
}
static
int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags)
{
#if HAVE_SOFIA_SMIME
int smime_enable = nua->sm->sm_enable;
int smime_opt = nua->sm->sm_opt;
int smime_protection_mode = nua->sm->sm_protection_mode;
char const *smime_message_digest = NONE;
char const *smime_signature = NONE;
char const *smime_key_encryption = NONE;
char const *smime_message_encryption = NONE;
char const *smime_path = NONE;
int n;
n = tl_gets(tags,
NUTAG_SMIME_ENABLE_REF(smime_enable),
NUTAG_SMIME_OPT_REF(smime_opt),
NUTAG_SMIME_PROTECTION_MODE_REF(smime_protection_mode),
NUTAG_SMIME_MESSAGE_DIGEST_REF(smime_message_digest),
NUTAG_SMIME_SIGNATURE_REF(smime_signature),
NUTAG_SMIME_KEY_ENCRYPTION_REF(smime_key_encryption),
NUTAG_SMIME_MESSAGE_ENCRYPTION_REF(smime_message_encryption),
NUTAG_CERTIFICATE_DIR_REF(smime_path),
TAG_NULL());
if (n <= 0)
return n;
/* XXX - all other S/MIME parameters? */
return sm_set_params(nua->sm, smime_enable, smime_opt,
smime_protection_mode, smime_path);
#endif
return 0;
}
/**@fn void nua_get_params(nua_t *nua, tag_type_t tag, tag_value_t value, ...)
*
* Get NUA parameters matching with the given filter.
* The values of NUA parameters is returned in #nua_r_get_params event.
*
* @param nua Pointer to NUA stack object
* @param tag, value, ... List of tagged parameters
*
* @return
* nothing
*
* @par Related tags:
* TAG_ANY() \n
* otherwise same tags as nua_set_params()
*
* @par Events:
* #nua_r_get_params
*
* @par Examples
* Find out default values of all parameters:
* @code
* nua_get_params(nua, TAG_ANY(), TAG_END());
* @endcode
*/
/**@fn void nua_get_hparams(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...)
*
* Get values of handle-specific parameters in #nua_r_get_params event.
*
* Application will specify either expilicit list of tags it is interested
* in, or a filter (at the moment, TAG_ANY()). The values are returned as a
* list of tags in the #nua_r_get_params event.
*
* @param nh Pointer to operation handle
* @param tag, value, ... List of tagged parameters
*
* The handle-specific parameters will contain only the parameters actually
* modified by application, either by nua_set_hparams() or some other
* handle-specific call. Currently, no NTA parameters are returned. They are
* returned only when application asks for user-agent-level parameters using
* either nua_get_params() or using default handle, eg.
* @code
* nua_get_hparams(nua_default(nua), TAG_ANY())
* @endcode
*
* @return
* nothing
*
* @par Related tags:
* #TAG_ANY \n
* othervise same tags as nua_set_hparams()
*
* @par Events:
* #nua_r_get_params
*/
/** @NUA_EVENT nua_r_get_params
*
* Answer to nua_get_params() or nua_get_hparams().
*
* @param status 200 when succesful, error code otherwise
* @param phrase a short textual description of @a status code
* @param nh NULL when responding to nua_get_params(),
* operation handle when responding to nua_get_hparams()
* @param hmagic NULL when responding to nua_get_params(),
* application contact associated with the operation handle
* when responding to nua_get_hparams()
* @param sip NULL
* @param tags
* NUTAG_APPL_METHOD() \n
* NUTAG_AUTH_CACHE() \n
* NUTAG_AUTOACK() \n
* NUTAG_AUTOALERT() \n
* NUTAG_AUTOANSWER() \n
* NUTAG_CALLEE_CAPS() \n
* NUTAG_DETECT_NETWORK_UPDATES() \n
* NUTAG_EARLY_ANSWER() \n
* NUTAG_EARLY_MEDIA() \n
* NUTAG_ENABLEINVITE() \n
* NUTAG_ENABLEMESSAGE() \n
* NUTAG_ENABLEMESSENGER() \n
* NUTAG_INITIAL_ROUTE() \n
* NUTAG_INITIAL_ROUTE_STR() \n
* NUTAG_INSTANCE() \n
* NUTAG_INVITE_TIMER() \n
* NUTAG_KEEPALIVE() \n
* NUTAG_KEEPALIVE_STREAM() \n
* NUTAG_MAX_SUBSCRIPTIONS() \n
* NUTAG_MEDIA_ENABLE() \n
* NUTAG_MEDIA_FEATURES() \n
* NUTAG_MIN_SE() \n
* NUTAG_M_DISPLAY() \n
* NUTAG_M_FEATURES() \n
* NUTAG_M_PARAMS() \n
* NUTAG_M_USERNAME() \n
* NUTAG_ONLY183_100REL() \n
* NUTAG_OUTBOUND() \n
* NUTAG_PATH_ENABLE() \n
* NUTAG_REFER_EXPIRES() \n
* NUTAG_REFER_WITH_ID() \n
* NUTAG_REGISTRAR() \n
* NUTAG_RETRY_COUNT() \n
* NUTAG_SERVICE_ROUTE_ENABLE() \n
* NUTAG_SESSION_REFRESHER() \n
* NUTAG_SESSION_TIMER() \n
* NUTAG_SMIME_ENABLE() \n
* NUTAG_SMIME_KEY_ENCRYPTION() \n
* NUTAG_SMIME_MESSAGE_DIGEST() \n
* NUTAG_SMIME_MESSAGE_ENCRYPTION() \n
* NUTAG_SMIME_OPT() \n
* NUTAG_SMIME_PROTECTION_MODE() \n
* NUTAG_SMIME_SIGNATURE() \n
* NUTAG_SOA_NAME() \n
* NUTAG_SUBSTATE() \n
* NUTAG_SUB_EXPIRES() \n
* NUTAG_UPDATE_REFRESH() \n
* NUTAG_USER_AGENT() \n
* SIPTAG_ALLOW() \n
* SIPTAG_ALLOW_STR() \n
* SIPTAG_ALLOW_EVENTS() \n
* SIPTAG_ALLOW_EVENTS_STR() \n
* SIPTAG_FROM() \n
* SIPTAG_FROM_STR() \n
* SIPTAG_ORGANIZATION() \n
* SIPTAG_ORGANIZATION_STR() \n
* SIPTAG_SUPPORTED() \n
* SIPTAG_SUPPORTED_STR() \n
* SIPTAG_USER_AGENT() \n
* SIPTAG_USER_AGENT_STR() \n
*
* @sa nua_get_params(), nua_get_hparams(),
* nua_set_params(), nua_set_hparams(), #nua_r_set_params
*
* @END_NUA_EVENT
*/
/**@internal
* Send a list of NUA parameters to the application.
*
* This function gets invoked when application calls either nua_get_params()
* or nua_get_hparams().
*
* The parameter tag list will initially contain all the relevant parameter
* tags, and it will be filtered down to parameters asked by application.
*
* The handle-specific parameters will contain only the parameters actually
* modified by application, either by nua_set_hparams() or some other
* handle-specific call. NTA parameters are returned only when application
* asks for user-agent-level parameters using nua_get_params().
*
*/
int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
tagi_t const *tags)
{
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;
sip_from_t from[1];
sip_contact_t const *m;
/* nta */
merge with sofia darcs trunk: Fri Oct 12 08:42:17 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Makefile.am: fixed ordering of SUBDIRS Fri Oct 12 13:32:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/utils/stunc.dsp: fixed include paths Fri Oct 12 13:32:19 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/tests/torture_su_root: fixed include paths Fri Oct 12 13:32:52 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32: added missing files from Makefile.am, .dsp, vproj Fri Oct 12 13:33:42 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/build_sources.cmd: added extra headers to sip_tag.c and sip_parser_table.c Fri Oct 12 13:37:00 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * win32/check.cmd: added option -a to relevant tests. Optionally check Release build. Fri Oct 12 13:37:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * url.h: silenced warning on URL_INIT_AS() Fri Oct 12 13:37:43 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * tstdef.h: silenced warnings on TEST_M() Fri Oct 12 13:38:15 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta_internal.h, nua_params.c: fixed NTATAG_UDP_MTU() type Fri Oct 12 13:39:06 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_class.h: fixed test_auth_class, test_numeric_class declaration Fri Oct 12 13:39:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed various tests on win32. Fri Oct 12 13:39:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * sip_basic.c: removed dead code Fri Oct 12 14:38:02 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nea_server.c: avoid raporting un-SUBSCRIBE twice Fri Oct 12 14:38:31 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * test_sip_events.c: checking some nua_i_notifier/nua_i_subscriber events Fri Oct 12 14:38:42 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged Release candidate 2 for 1.12.7 Mon Oct 15 04:03:22 EDT 2007 Pekka.Pessi@nokia.com * configure.ac, RELEASE: version 1.12.7 Mon Oct 15 08:27:13 EDT 2007 Pekka.Pessi@nokia.com * open_c: included in the dist Tue Oct 16 08:07:46 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: Open C fixes Wed Oct 17 06:50:11 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua.docs: replace reference to nua_cli.c with sofsip_cli Wed Oct 17 08:43:11 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged rel-sofia-sip-1_12_7 Wed Oct 17 08:43:15 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged 1.12.7 Wed Oct 17 11:01:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * libsofia-sip-ua/su/Makefile.am: fixed problem with automake 1.9 Wed Oct 17 11:13:15 EDT 2007 Pekka.Pessi@nokia.com * configure.ac, RELEASE: opened tree for development Tue Oct 23 10:45:17 EDT 2007 Pekka.Pessi@nokia.com * su_alloc.c: fixed su_home_init() (not initializing pointer to mutexes) Thu Oct 25 13:15:45 EDT 2007 Pekka.Pessi@nokia.com * nua_notifier.c: updated nua_i_subscribe, nua_notify() and nua_r_notify documentation Wed Nov 7 07:58:08 EST 2007 Pekka.Pessi@nokia.com * sofia-sip/htable2.h: fixed HTABLE_PROTOS2() git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6219 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-11-12 16:04:47 +00:00
unsigned udp_mtu = 0;
usize_t max_proceeding = 0;
unsigned sip_t1 = 0, sip_t2 = 0, sip_t4 = 0, sip_t1x64 = 0;
unsigned debug_drop_prob = 0;
url_string_t const *proxy = NULL;
sip_contact_t const *aliases = NULL;
unsigned flags = 0;
/* soa */
tagi_t *media_params = NULL;
su_home_t tmphome[SU_HOME_AUTO_SIZE(16536)];
enter;
if (nh == dnh)
nta_agent_get_params(nua->nua_nta,
NTATAG_UDP_MTU_REF(udp_mtu),
NTATAG_MAX_PROCEEDING_REF(max_proceeding),
NTATAG_SIP_T1_REF(sip_t1),
NTATAG_SIP_T2_REF(sip_t2),
NTATAG_SIP_T4_REF(sip_t4),
NTATAG_SIP_T1X64_REF(sip_t1x64),
NTATAG_DEBUG_DROP_PROB_REF(debug_drop_prob),
NTATAG_DEFAULT_PROXY_REF(proxy),
NTATAG_ALIASES_REF(aliases),
NTATAG_SIPFLAGS_REF(flags),
TAG_END());
if (nh->nh_ds->ds_local)
has_from = 1, *from = *nh->nh_ds->ds_local, from->a_params = NULL;
sync to the 1.12.6work3 (1.12.7 pre-release) from darcs: Mon Oct 8 15:00:04 EDT 2007 Pekka Pessi <first.lastname@nokia.com> * tport: fixed problem with tls send blocking Wed Oct 10 13:55:25 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * Fixed the internal type of statistics Thu Oct 11 11:25:59 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fix sf.net bug #1810115, crash after nta_destroy() su_msg_t delivery, again. Thanks to Mikhail Zabaluev for reporting this. Thu Oct 11 11:45:20 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nta: fixed type checking on NTATAG_UDP_MTU()/NTATAG_UDP_MTU_REF() Thu Oct 11 13:25:12 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * nua: fixed the from header handling The agent-level From header no longer overrides the From header set by nua_invite() and friends. Thanks to Fabio Margarido for keeping reporting about the problem. Thu Oct 11 13:28:58 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * RELEASE: updated Thu Oct 11 11:30:13 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * torture_sresolv.c: fixed printf() formatting types Passed a size_t to %u. Thu Oct 11 11:44:54 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> * rules/sofia.am: not using make -C dir Thu Oct 11 14:16:51 EDT 2007 Pekka Pessi <Pekka.Pessi@nokia.com> tagged release candidate 1 for 1.12.7 Thu Oct 11 12:25:28 EDT 2007 Pekka.Pessi@nokia.com * su_clone_start(): fixed spurious release of a pthreaded port git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5842 d0543943-73ff-0310-b7d9-9358b9ac24b2
2007-10-11 19:58:13 +00:00
else /* if (nua->nua_from_is_set) */
has_from = 1, *from = *nua->nua_from;
media_params = soa_get_paramlist(nh->nh_soa, TAG_END());
m = nua_stack_get_contact(nua->nua_registrations);
/* Include tag in the list returned to user
* if it has been earlier set (by user) */
#define TIF(TAG, pref) \
TAG_IF(nhp->nhp_set.nhb_##pref, TAG(nhp->nhp_##pref))
/* Include tag in the list returned to user
* if it has been earlier set (by user)
* but always include in the default parameters */
#define TIFD(TAG, pref) \
TAG_IF(nh == dnh || nhp->nhp_set.nhb_##pref, TAG(nhp->nhp_##pref))
/* Include string tag made out of SIP header
* if it has been earlier set (by user) */
#define TIF_STR(TAG, pref) \
TAG_IF(nhp->nhp_set.nhb_##pref, \
TAG(nhp->nhp_set.nhb_##pref && nhp->nhp_##pref \
? sip_header_as_string(tmphome, (void *)nhp->nhp_##pref) : NULL))
/* Include header tag made out of string
* if it has been earlier set (by user) */
#define TIF_SIP(TAG, pref) \
TAG_IF(nhp->nhp_set.nhb_##pref, \
TAG(nhp->nhp_set.nhb_##pref && nhp->nhp_##pref \
? 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
(tmphome, tags,
TAG_IF(has_from, SIPTAG_FROM(from)),
TAG_IF(has_from,
SIPTAG_FROM_STR(has_from
? sip_header_as_string(tmphome, (void *)from)
: NULL)),
TIF(NUTAG_RETRY_COUNT, retry_count),
TIF(NUTAG_MAX_SUBSCRIPTIONS, max_subscriptions),
TIF(NUTAG_SOA_NAME, soa_name),
TIF(NUTAG_MEDIA_ENABLE, media_enable),
TIF(NUTAG_ENABLEINVITE, invite_enable),
TIF(NUTAG_AUTOALERT, auto_alert),
TIF(NUTAG_EARLY_ANSWER, early_answer),
TIF(NUTAG_EARLY_MEDIA, early_media),
TIF(NUTAG_ONLY183_100REL, only183_100rel),
TIF(NUTAG_AUTOANSWER, auto_answer),
TIF(NUTAG_AUTOACK, auto_ack),
TIF(NUTAG_INVITE_TIMER, invite_timeout),
TIFD(NUTAG_SESSION_TIMER, session_timer),
TIF(NUTAG_MIN_SE, min_se),
TIFD(NUTAG_SESSION_REFRESHER, refresher),
TIF(NUTAG_UPDATE_REFRESH, update_refresh),
TIF(NUTAG_ENABLEMESSAGE, message_enable),
TIF(NUTAG_ENABLEMESSENGER, win_messenger_enable),
/* TIF(NUTAG_AUTORESPOND, autorespond), */
TIF(NUTAG_CALLEE_CAPS, callee_caps),
TIF(NUTAG_MEDIA_FEATURES, media_features),
TIF(NUTAG_SERVICE_ROUTE_ENABLE, service_route_enable),
TIF(NUTAG_PATH_ENABLE, path_enable),
TIF(NUTAG_AUTH_CACHE, auth_cache),
TIF(NUTAG_REFER_EXPIRES, refer_expires),
TIF(NUTAG_REFER_WITH_ID, refer_with_id),
TIF(NUTAG_SUBSTATE, substate),
TIF(NUTAG_SUB_EXPIRES, sub_expires),
TIF(SIPTAG_SUPPORTED, supported),
TIF_STR(SIPTAG_SUPPORTED_STR, supported),
TIF(SIPTAG_ALLOW, allow),
TIF_STR(SIPTAG_ALLOW_STR, allow),
TIF_STR(NUTAG_APPL_METHOD, appl_method),
TIF(SIPTAG_ALLOW_EVENTS, allow_events),
TIF_STR(SIPTAG_ALLOW_EVENTS_STR, allow_events),
TIF_SIP(SIPTAG_USER_AGENT, user_agent),
TIF(SIPTAG_USER_AGENT_STR, user_agent),
TIF(NUTAG_USER_AGENT, user_agent),
TIF_SIP(SIPTAG_ORGANIZATION, organization),
TIF(SIPTAG_ORGANIZATION_STR, organization),
TIF(NUTAG_INITIAL_ROUTE, initial_route),
TIF_STR(NUTAG_INITIAL_ROUTE_STR, initial_route),
TIF(NUTAG_REGISTRAR, registrar),
TIF(NUTAG_KEEPALIVE, keepalive),
TIF(NUTAG_KEEPALIVE_STREAM, keepalive_stream),
TIF(NUTAG_INSTANCE, instance),
TIF(NUTAG_M_DISPLAY, m_display),
TIF(NUTAG_M_USERNAME, m_username),
TIF(NUTAG_M_PARAMS, m_params),
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)),
/* Include tag in the list returned to user
* if it has been earlier set (by user) */
#define GIF(TAG, pref) \
TAG_IF(ngp->ngp_set.ngp_##pref, TAG(ngp->ngp_##pref))
GIF(NUTAG_DETECT_NETWORK_UPDATES, detect_network_updates),
GIF(NUTAG_SHUTDOWN_EVENTS, shutdown_events),
NTATAG_CONTACT(m),
#if HAVE_SOFIA_SMIME
NUTAG_SMIME_ENABLE(nua->sm->sm_enable),
NUTAG_SMIME_OPT(nua->sm->sm_opt),
NUTAG_SMIME_PROTECTION_MODE(nua->sm->sm_protection_mode),
NUTAG_SMIME_MESSAGE_DIGEST(nua->sm->sm_message_digest),
NUTAG_SMIME_SIGNATURE(nua->sm->sm_signature),
NUTAG_SMIME_KEY_ENCRYPTION(nua->sm->sm_key_encryption),
NUTAG_SMIME_MESSAGE_ENCRYPTION(nua->sm->sm_message_encryption),
#endif
NTATAG_UDP_MTU(udp_mtu),
NTATAG_MAX_PROCEEDING(max_proceeding),
NTATAG_SIP_T1(sip_t1),
NTATAG_SIP_T2(sip_t2),
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),
TAG_NEXT(media_params));
nua_stack_event(nua, nh, NULL, nua_r_get_params, SIP_200_OK, lst);
su_home_deinit(tmphome);
tl_vfree(media_params);
return 0;
}