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