📄 nua_params.c
字号:
/* * 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_STRCASESTRchar *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_VERSIONstatic 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]; 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); 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; 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); } set = 0; } if (!f) return -1; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -