diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c index 35b59d16ed..285237a266 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_notifier.c @@ -237,8 +237,7 @@ int nua_subscribe_server_preprocess(nua_server_request_t *sr) sip_event_t *o = sip->sip_event; char const *event = o ? o->o_type : NULL; /* Maximum expiration time */ - unsigned long expires = sip->sip_expires ? sip->sip_expires->ex_delta : 3600; - sip_time_t now = sip_now(); + unsigned long expires = 3600; assert(nh && nh->nh_nua->nua_dhandle != nh); @@ -260,10 +259,9 @@ int nua_subscribe_server_preprocess(nua_server_request_t *sr) nu = nua_dialog_usage_private(du); - if (now + expires >= now) - nu->nu_requested = now + expires; - else - nu->nu_requested = SIP_TIME_MAX - 1; + if (sip->sip_expires && sip->sip_expires->ex_delta < expires) + expires = sip->sip_expires->ex_delta; + nu->nu_requested = sip_now() + expires; #if SU_HAVE_EXPERIMENTAL nu->nu_etags = @@ -297,23 +295,9 @@ int nua_subscribe_server_respond(nua_server_request_t *sr, tagi_t const *tags) sip_time_t now = sip_now(); if (nu->nu_requested) { - if (sip->sip_expires) { - /* Expires in response can only shorten the expiration time */ - if (nu->nu_requested > now + sip->sip_expires->ex_delta) - nu->nu_requested = now + sip->sip_expires->ex_delta; - } - else { - unsigned sub_expires = NH_PGET(sr->sr_owner, sub_expires); - if (nu->nu_requested > now + sub_expires) - nu->nu_requested = now + sub_expires; - } - - if (nu->nu_requested >= now) + if (nu->nu_requested > nu->nu_expires) nu->nu_expires = nu->nu_requested; - else - nu->nu_expires = now; - - if (nu->nu_expires <= now) + else if (nu->nu_expires <= now || nu->nu_requested <= now) nu->nu_substate = nua_substate_terminated; } @@ -321,7 +305,7 @@ int nua_subscribe_server_respond(nua_server_request_t *sr, tagi_t const *tags) ex->ex_delta = nu->nu_expires - now; } else { - /* Always add header Expires: 0 */ + /* Add header Expires: 0 */ } if (!sip->sip_expires || sip->sip_expires->ex_delta > ex->ex_delta) diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c index 5568639b23..b7bfea378c 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c @@ -77,27 +77,19 @@ su_inline int nhp_is_any_set(nua_handle_preferences_t const *nhp) 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]; - - /* - unsigned *ap, const *bp; + unsigned *ap = a->nhp_set_.set_unsigned; + unsigned const *bp = b->nhp_set_.set_unsigned; size_t i; - ap = a->nhp_set_.set_unsigned; - bp = b->nhp_set_.set_unsigned; + memcpy(a, b, offsetof(nua_handle_preferences_t, nhp_set)); + for (i = 0; i < (sizeof a->nhp_set); i += (sizeof *ap)) *ap++ |= *bp++; - - */ } static int nhp_set_tags(su_home_t *home, nua_handle_preferences_t *nhp, - nua_global_preferences_t *ngp, + int global, tagi_t const *tags); static int nhp_merge_lists(su_home_t *home, @@ -109,11 +101,11 @@ static int nhp_merge_lists(su_home_t *home, 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); - +static +nua_handle_preferences_t *nhp_move_params(su_home_t *home, + nua_handle_preferences_t *dst, + su_home_t *tmphome, + nua_handle_preferences_t const *src); /* ====================================================================== */ /* Magical NUTAG_USER_AGENT() - add NHP_USER_AGENT there if it is not there */ @@ -207,12 +199,20 @@ int nua_stack_set_from(nua_t *nua, int initial, tagi_t const *tags) sip_from_t *f = NULL, f0[1]; int set; + char const *uicc_name = "default"; + tl_gets(tags, /* By nua_stack_set_from() */ SIPTAG_FROM_REF(from), SIPTAG_FROM_STR_REF(str), + NUTAG_UICC_REF(uicc_name), TAG_END()); +#if HAVE_UICC_H + if (initial && uicc_name) + nua->nua_uicc = uicc_create(root, uicc_name); +#endif + if (!initial && from == NONE && str == NONE) return 0; @@ -326,7 +326,6 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags) * 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 @@ -439,7 +438,6 @@ int nua_stack_init_instance(nua_handle_t *nh, tagi_t const *tags) * 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 @@ -478,124 +476,146 @@ 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], *nhp = nh->nh_prefs; + nua_handle_preferences_t const *dnhp = dnh->nh_prefs; + + su_home_t tmphome[1] = { SU_HOME_INIT(tmphome) }; + + tagi_t const *ptags; + + int error, global; + int status = 900; + char const *phrase = "Error storing parameters"; + sip_supported_t const *supported = NULL; + sip_allow_t const *allow = NULL; + sip_allow_events_t const *allow_events = NULL; + sip_allow_t const *appl_method = NULL; enter; - { - su_home_t tmphome[1] = { SU_HOME_INIT(tmphome) }; - nua_handle_preferences_t *nhp = nh->nh_prefs; - nua_handle_preferences_t const *dnhp = dnh->nh_prefs; - nua_handle_preferences_t tmp[1]; - nua_global_preferences_t gtmp[1], *ngp = NULL; + ptags = !nh->nh_used_ptags ? nh->nh_ptags : NULL; - *tmp = *nhp; NHP_UNSET_ALL(tmp); + *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; + /* Supported features, allowed methods and events are merged + with previous ones */ + if (!NHP_ISSET(nhp, supported)) + supported = tmp->nhp_supported = dnhp->nhp_supported; + if (!NHP_ISSET(nhp, allow)) + allow = tmp->nhp_allow = dnhp->nhp_allow; + if (!NHP_ISSET(nhp, allow_events)) + allow_events = tmp->nhp_allow_events = dnhp->nhp_allow_events; + if (!NHP_ISSET(nhp, appl_method)) + appl_method = tmp->nhp_appl_method = dnhp->nhp_appl_method; + + error = 0; + global = nh == dnh; /* save also stack-specific params */ - 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 (nhp_set_tags(tmphome, tmp, global, ptags) < 0) + error = 1, phrase = "Error storing default handle parameters"; + else if (nhp_set_tags(tmphome, tmp, global, tags) < 0) + error = 1, phrase = "Error storing parameters"; + else { + if (NHP_IS_ANY_SET(tmp)) { + if (tmp->nhp_supported == supported) + tmp->nhp_supported = NULL; - /* 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 (nhp_save_params(nh, tmphome, ngp, tmp) < 0) - status = 900, phrase = su_strerror(ENOMEM); - else - status = 200, phrase = "OK", nh->nh_used_ptags = 1; + if (tmp->nhp_allow == allow) + tmp->nhp_allow = NULL; - su_home_deinit(tmphome); + if (tmp->nhp_allow_events == allow_events) + tmp->nhp_allow_events = NULL; + + if (tmp->nhp_appl_method == appl_method) + tmp->nhp_appl_method = NULL; + + /* Move parameters from tmp to nhp (or allocate new nhp) */ + if (nh != dnh && nhp == dnh->nh_prefs) + nhp = NULL; + nhp = nhp_move_params(nh->nh_home, nhp, tmphome, tmp); + + if (nhp) + nh->nh_prefs = nhp; + else + /* Fail miserably with ENOMEM */ + error = 1, status = 900, phrase = su_strerror(ENOMEM); + } + + if (!error) + nh->nh_used_ptags = 1; } - if (status == 200) { - nua_handle_preferences_t const *nhp = nh->nh_prefs; - nua_handle_preferences_t const *dnhp = dnh->nh_prefs; + su_home_deinit(tmphome); - 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 (error) + ; + else 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 (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 (status == 200 && tags && nh->nh_soa && - soa_set_params(nh->nh_soa, TAG_NEXT(tags)) < 0) - status = 900, phrase = "Error Setting SOA Parameters"; + ptags = nh->nh_ptags; + + if (!nh->nh_soa) + error = 1, status = 900, phrase = "Error Creating SOA Object"; + } + 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 && 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 (!error && nh->nh_soa) { + if ((ptags && soa_set_params(nh->nh_soa, TAG_NEXT(ptags)) < 0) || + (tags && soa_set_params(nh->nh_soa, TAG_NEXT(tags)) < 0)) + error = 1, status = 900, phrase = "Error Setting SOA Parameters"; } - if (status != 200) { + if (error || nh != dnh) { + ; + } + else if (nua_stack_set_smime_params(nua, tags) < 0) { + error = 1, status = 900, phrase = "Error setting S/MIME parameters"; + } + else if (!nua->nua_nta) { + } + /* Set stack-specific things below */ + else if (nta_agent_set_params(nua->nua_nta, TAG_NEXT(tags)) < 0) { + status = 900, phrase = "Error setting NTA parameters"; + error = 1; + } + else { + nua_stack_set_from(nua, 0, tags); + if (NHP_ISSET(nhp, detect_network_updates)) + nua_stack_launch_network_change_detector(nua); + } + + if (error) { 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); - return 0; - } + + if (e == nua_r_set_params) + UA_EVENT2(e, 200, "OK"); + + return 0; } - -/** Parse parameters from tags to @a nhp or @a ngp. +/** Parse parameters from tags to @a nhp. * * @param home allocate new values from @a home * @param nhp structure to store handle preferences - * @param ngp structure to store global preferences + * @param global if true, save also global parameters * @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, + int global, tagi_t const *tags) { @@ -807,10 +827,6 @@ static int nhp_set_tags(su_home_t *home, 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); @@ -982,7 +998,7 @@ static int nhp_set_tags(su_home_t *home, NHP_SET_STR(nhp, outbound, value); } /* NUTAG_DETECT_NETWORK_UPDATES(detect_network_updates) */ - else if (ngp && tag == nutag_detect_network_updates) { + else if (global && tag == nutag_detect_network_updates) { int detector = (int)value; if (detector < NUA_NW_DETECT_NOTHING) @@ -990,13 +1006,7 @@ static int nhp_set_tags(su_home_t *home, 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; + NHP_SET(nhp, detect_network_updates, detector); } } @@ -1069,70 +1079,54 @@ static int nhp_merge_lists(su_home_t *home, return 1; } -/** Save parameters in @a gtmp and @a tmp. - */ -static -int nhp_save_params(nua_handle_t *nh, - su_home_t *tmphome, - nua_global_preferences_t *gsrc, - nua_handle_preferences_t *src) +static +nua_handle_preferences_t *nhp_move_params(su_home_t *home, + nua_handle_preferences_t *dst, + su_home_t *tmphome, + nua_handle_preferences_t const *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]; + /* Update prefs structure */ + nua_handle_preferences_t tbf[1]; - if (gsrc) { - *nua->nua_prefs = *gsrc; /* No pointers this far */ - } + if (dst == NULL) + dst = su_zalloc(home, sizeof *dst); + if (dst == NULL) + return NULL; + if (su_home_move(home, tmphome) < 0) + return NULL; - if (!NHP_IS_ANY_SET(src)) - return 0; - - if (nh == dnh || nh->nh_prefs != dnh->nh_prefs) { - dst = nh->nh_prefs, *old = *dst; - assert(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 */ + *tbf = *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)) +#define NHP_ZAP_OVERRIDEN(tbf, nhp, pref) \ + (((tbf)->nhp_set.nhb_##pref \ + && (tbf)->nhp_##pref != (nhp)->nhp_##pref \ + ? su_free(home, (void *)(tbf)->nhp_##pref) : (void)0), \ + (void)(!(nhp)->nhp_set.nhb_##pref ? (nhp)->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); + NHP_ZAP_OVERRIDEN(tbf, dst, soa_name); + NHP_ZAP_OVERRIDEN(tbf, dst, registrar); + NHP_ZAP_OVERRIDEN(tbf, dst, supported); + NHP_ZAP_OVERRIDEN(tbf, dst, allow); + NHP_ZAP_OVERRIDEN(tbf, dst, user_agent); + NHP_ZAP_OVERRIDEN(tbf, dst, organization); + NHP_ZAP_OVERRIDEN(tbf, dst, instance); + NHP_ZAP_OVERRIDEN(tbf, dst, m_display); + NHP_ZAP_OVERRIDEN(tbf, dst, m_username); + NHP_ZAP_OVERRIDEN(tbf, dst, m_params); + NHP_ZAP_OVERRIDEN(tbf, dst, m_features); + NHP_ZAP_OVERRIDEN(tbf, dst, outbound); - nh->nh_prefs = dst; - - return 0; +#define NHP_ZAP_OVERRIDEN_HDR(tbf, nhp, pref) \ + (((tbf)->nhp_set.nhb_##pref \ + && (tbf)->nhp_##pref != (nhp)->nhp_##pref \ + ? msg_header_free(home, (void *)(tbf)->nhp_##pref) : (void)0), \ + (void)(!(nhp)->nhp_set.nhb_##pref ? (nhp)->nhp_##pref = NULL : NULL)) + + NHP_ZAP_OVERRIDEN_HDR(tbf, dst, initial_route); + + return dst; } static int nua_handle_tags_filter(tagi_t const *f, tagi_t const *t); @@ -1482,7 +1476,6 @@ int nua_stack_set_smime_params(nua_t *nua, tagi_t const *tags) * 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 @@ -1523,7 +1516,6 @@ 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; tagi_t *lst; @@ -1549,6 +1541,8 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, enter; + su_home_auto(tmphome, sizeof(tmphome)); + nta_agent_get_params(nua->nua_nta, NTATAG_UDP_MTU_REF(udp_mtu), NTATAG_MAX_PROCEEDING_REF(max_proceeding), @@ -1597,8 +1591,6 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, ? sip_##pref##_make(tmphome, (char *)nhp->nhp_##pref) \ : NULL)) - su_home_auto(tmphome, sizeof(tmphome)); - lst = tl_filtered_tlist (tmphome, tags, TAG_IF(has_from, SIPTAG_FROM(from)), @@ -1639,7 +1631,6 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, 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), @@ -1668,18 +1659,11 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e, TIF(NUTAG_M_PARAMS, m_params), TIF(NUTAG_M_FEATURES, m_features), TIF(NUTAG_OUTBOUND, outbound), + TIF(NUTAG_DETECT_NETWORK_UPDATES, detect_network_updates), /* 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 diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h index a9993fe9a3..70df87f6d8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h @@ -107,7 +107,6 @@ typedef struct nua_handle_preferences /* Subscriber state, i.e. nua_substate_pending */ unsigned nhp_substate; - unsigned nhp_sub_expires; /* REGISTER keepalive intervals */ unsigned nhp_keepalive, nhp_keepalive_stream; @@ -128,6 +127,9 @@ typedef struct nua_handle_preferences /** Outbound OPTIONS */ char const *nhp_outbound; + /** Network detection: NONE, INFORMAL, TRY_FULL */ + int nhp_detect_network_updates; + sip_allow_t *nhp_appl_method; /** Initial route set */ @@ -135,12 +137,6 @@ typedef struct nua_handle_preferences union { struct { /* A bit for each feature set by application */ - /* NOTE: - Some compilers behave weird if there are bitfields - together with width > 32 - So there should be a padding field (unsigned:0;) - every 32 bits. - */ unsigned nhb_retry_count:1; unsigned nhb_max_subscriptions:1; @@ -170,15 +166,13 @@ typedef struct nua_handle_preferences unsigned nhb_refer_with_id:1; unsigned nhb_refer_expires:1; unsigned nhb_substate:1; - unsigned nhb_sub_expires:1; unsigned nhb_keepalive:1; unsigned nhb_keepalive_stream:1; unsigned nhb_registrar:1; unsigned nhb_allow:1; - unsigned :0; /* at most 32 bits before this point */ unsigned nhb_supported:1; - + unsigned :0; /* at most 32 bits ... */ unsigned nhb_allow_events:1; unsigned nhb_user_agent:1; unsigned nhb_organization:1; @@ -189,6 +183,7 @@ typedef struct nua_handle_preferences unsigned nhb_m_features:1; unsigned nhb_instance:1; unsigned nhb_outbound:1; + unsigned nhb_detect_network_updates:1; unsigned nhb_appl_method:1; unsigned nhb_initial_route:1; unsigned :0; @@ -199,26 +194,6 @@ typedef struct nua_handle_preferences #define nhp_set nhp_set_.set_bits -/** Global preferences for nua. */ -typedef struct { - /** Network detection: NONE, INFORMAL, TRY_FULL */ - signed int ngp_detect_network_updates:3; - /** Pass events during shutdown, too */ - int ngp_shutdown_events:1; - - unsigned :0; /* pad */ - union { struct { - /* A bit for each feature set by application */ - unsigned ngp_detect_network_updates:1; - unsigned ngp_shutdown_events:1; - unsigned :0; - } set_bits; - unsigned set_unsigned[2]; - } ngp_set_; -} nua_global_preferences_t; - -#define ngp_set ngp_set_.set_bits - #define DNHP_GET(dnhp, pref) ((dnhp)->nhp_##pref) #define NHP_GET(nhp, dnhp, pref) \ diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 393f9e11e0..ba6ea387d2 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -1854,8 +1854,9 @@ nua_invite_server_init(nua_server_request_t *sr) nua_client_request_t const *cr; for (sr0 = nh->nh_ds->ds_sr; sr0; sr0 = sr0->sr_next) { - /* Previous INVITE has not been ACKed */ - if (sr0->sr_method == sip_method_invite) + /* Final response have not been sent to previous INVITE */ + if (sr0->sr_method == sip_method_invite && + nua_server_request_is_pending(sr0)) break; /* Or we have sent offer but have not received an answer */ if (sr->sr_sdp && sr0->sr_offer_sent && !sr0->sr_answer_recv) @@ -1878,8 +1879,10 @@ nua_invite_server_init(nua_server_request_t *sr) ss = nua_dialog_usage_private(sr->sr_usage); - if (ss->ss_state < nua_callstate_ready && + if (ss->ss_state < nua_callstate_completed && ss->ss_state != nua_callstate_init) { + /* We should never trigger this, + but better not to assert() on network input */ return nua_server_retry_after(sr, 500, "Overlapping Requests 2", 0, 10); } } @@ -1914,7 +1917,7 @@ nua_session_server_init(nua_server_request_t *sr) else if (sr->sr_usage) { nua_session_usage_t *ss = nua_dialog_usage_private(sr->sr_usage); if (ss->ss_state >= nua_callstate_terminating) - return SR_STATUS(sr, 481, "Call is being terminated"); + return SR_STATUS1(sr, 481, "Call is being terminated"); } if (nh->nh_soa) { diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c index bc5e626277..0d23077c8d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c @@ -209,7 +209,7 @@ int nua_stack_init(su_root_t *root, nua_t *nua) if (nua_stack_set_from(nua, 1, nua->nua_args) < 0) return -1; - if (nua->nua_prefs->ngp_detect_network_updates) + if (NHP_ISSET(dnh->nh_prefs, detect_network_updates)) nua_stack_launch_network_change_detector(nua); nua_stack_timer(nua, nua->nua_timer, NULL); @@ -293,8 +293,7 @@ int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg, if ((event > nua_r_authenticate && event <= nua_r_ack) || event < nua_i_error || (nh && !nh->nh_valid) - || (nua->nua_shutdown && event != nua_r_shutdown && - !nua->nua_prefs->ngp_shutdown_events)) { + || (nua->nua_shutdown && event != nua_r_shutdown)) { if (msg) msg_destroy(msg); return event; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h index cf6f9c4595..de99527258 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h @@ -217,31 +217,28 @@ struct nua_s { su_clone_r nua_clone; su_task_r nua_client; + su_network_changed_t *nua_nw_changed; + nua_callback_f nua_callback; nua_magic_t *nua_magic; nua_event_frame_t *nua_current; nua_saved_event_t nua_signal[1]; - /**< Used by stop-and-wait args calls */ - tagi_t const *nua_args; - /* Engine state flags */ - sip_time_t nua_shutdown; - unsigned nua_shutdown_started:1; /**< Shutdown initiated */ unsigned nua_shutdown_final:1; /**< Shutdown is complete */ unsigned nua_from_is_set; unsigned :0; - /**< Local SIP address. Contents are kept around for ever. */ - sip_from_t nua_from[1]; + /**< Used by stop-and-wait args calls */ + tagi_t const *nua_args; - /* ---------------------------------------------------------------------- */ + /**< Local SIP address. Contents are kept around for ever. */ + sip_from_t nua_from[1]; /* Protocol (server) side */ - su_network_changed_t *nua_nw_changed; nua_registration_t *nua_registrations; /**< Active registrations */ @@ -253,8 +250,21 @@ struct nua_s { nta_agent_t *nua_nta; su_timer_t *nua_timer; + void *nua_sip_parser; + + sip_time_t nua_shutdown; + + /* Route */ + sip_service_route_t *nua_service_route; + /* User-agent parameters */ - nua_global_preferences_t nua_prefs[1]; + unsigned nua_media_enable:1; + + unsigned :0; + +#if HAVE_SMIME /* Start NRC Boston */ + sm_object_t *sm; +#endif /* End NRC Boston */ nua_handle_t *nua_handles; nua_handle_t **nua_handles_tail; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c index 6207e73581..1a33530b09 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_subnotref.c @@ -371,9 +371,6 @@ static int nua_subscribe_client_response(nua_client_request_t *cr, else delta = 0; - if (delta > eu->eu_expires) - delta = eu->eu_expires; - if (win_messenger_enable && !nua_dialog_is_established(nh->nh_ds)) { /* Notify from messanger does not match with dialog tag */ nh->nh_ds->ds_remote_tag = su_strdup(nh->nh_home, ""); @@ -382,23 +379,23 @@ static int nua_subscribe_client_response(nua_client_request_t *cr, if (delta > 0) { nua_dialog_usage_set_refresh(du, delta); } - else { - if (eu->eu_substate == nua_substate_terminated) { - if (!eu->eu_notified) - eu->eu_substate = nua_substate_embryonic; - } + else if (!eu->eu_notified) { + /* This is a fetch: subscription was really terminated + but we wait 32 seconds for NOTIFY. */ + delta = 64 * NTA_SIP_T1 / 1000; - if (eu->eu_substate != nua_substate_terminated) { - /* Wait 32 seconds for NOTIFY. */ - delta = 64 * NTA_SIP_T1 / 1000; + if (win_messenger_enable) + delta = 4 * 60; /* Wait 4 minutes for NOTIFY from Messenger */ + + eu->eu_final_wait = 1; - eu->eu_final_wait = 1; + if (eu->eu_substate == nua_substate_terminated) + eu->eu_substate = nua_substate_embryonic; - if (!eu->eu_notified && win_messenger_enable) - delta = 4 * 60; /* Wait 4 minutes for NOTIFY from Messenger */ - - nua_dialog_usage_set_refresh_range(du, delta, delta); - } + nua_dialog_usage_set_refresh_range(du, delta, delta); + } + else { + eu->eu_substate = nua_substate_terminated; } substate = eu->eu_substate; @@ -653,6 +650,8 @@ int nua_notify_server_report(nua_server_request_t *sr, tagi_t const *tags) if (substate == nua_substate_active || substate == nua_substate_pending) { if (subs && subs->ss_expires) delta = strtoul(subs->ss_expires, NULL, 10); + else + delta = eu->eu_expires; } else if (substate == nua_substate_embryonic) { if (subs && subs->ss_reason) { @@ -690,8 +689,7 @@ int nua_notify_server_report(nua_server_request_t *sr, tagi_t const *tags) nua_dialog_usage_set_refresh_range(du, retry, retry + 5); } else { - if (delta < SIP_TIME_MAX) - nua_dialog_usage_set_refresh(du, delta); + nua_dialog_usage_set_refresh(du, delta); } return retval; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c index cf40cd890f..88686a7454 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c @@ -227,22 +227,21 @@ * - NUTAG_ALLOW_EVENTS(), SIPTAG_ALLOW_EVENTS(), and * SIPTAG_ALLOW_EVENTS_STR() * - NUTAG_MAX_SUBSCRIPTIONS() - * - NUTAG_SUBSTATE(), NUTAG_SUB_EXPIRES() + * - NUTAG_SUBSTATE() * @par Specifications * - @RFC3265 * * @par SIP Event Subscriber * - nua_subscribe(), #nua_r_subscribe, #nua_i_notify, NUTAG_SUBSTATE(), - * SIPTAG_EVENT(), SIPTAG_EXPIRES() + * SIPTAG_EVENT(), SIPTAG_EXPIRES(), * - nua_unsubscribe(), #nua_r_unsubscribe() * @par Specifications * - @RFC3265 * * @par SIP Event Notifier * - #nua_i_subscribe(), nua_notify(), #nua_r_notify, - * NUTAG_SUBSTATE(), NUTAG_SUB_EXPIRES(), SIPTAG_EVENT() + * NUTAG_SUBSTATE(), SIPTAG_EVENT() * Settings: - * - NUTAG_SUB_EXPIRES() * - NUTAG_ALLOW_EVENTS(), SIPTAG_ALLOW_EVENTS(), and * SIPTAG_ALLOW_EVENTS_STR() * - NUTAG_ALLOW("SUBSCRIBE"), NUTAG_APPL_METHOD("SUBSCRIBE") @@ -268,8 +267,6 @@ * Settings: * - NUTAG_ALLOW(x), NUTAG_APPL_METHOD(x) * - * @par Server Shutdown - * - nua_shutdown(), NUTAG_SHUTDOWN_EVENTS(), nua_destroy(). */ /* @par S/MIME @@ -770,14 +767,14 @@ tag_typedef_t nutag_answer_sent = BOOLTAG_TYPEDEF(answer_sent); * * @par Used with * - with nua_create(), nua_set_params(), nua_get_params(), - * nua_handle(), nua_set_hparams(), nua_get_hparams(), and - * nua_notifier() to change the default subscription state returned by - * the internal event server + * nua_handle(), nua_set_hparams(), nua_get_hparams(), and + * nua_notifier() to change the default subscription state returned by + * the intenal event server * - with nua_notify() and nua_respond() to SUBSCRIBE to determine the - * subscription state (if application include @SubscriptionState - * header in the tag list, the NUTAG_SUBSTATE() value is ignored) + * subscription state (if application include @SubscriptionState + * header in the tag list, the NUTAG_SUBSTATE() value is ignored) * - with #nua_r_subscribe, #nua_i_notify, #nua_i_subscribe, and #nua_r_notify - * to indicate the current subscription state + * to indicate the current subscription state * * @par Parameter type * int @@ -809,39 +806,6 @@ tag_typedef_t nutag_substate = INTTAG_TYPEDEF(substate); */ -/**@def NUTAG_SUB_EXPIRES() - * - * Default expiration time of subscriptions. - * - * @par Used with - * - with nua_create(), nua_set_params(), nua_get_params(), nua_handle(), - * nua_set_hparams(), nua_get_hparams(), nua_respond(), nua_notify(), and - * nua_notifier() to change the default expiration time of subscriptions - * - * @par Parameter type - * unsigned int - * - * @par Values - * - default expiration time in seconds - * - * Note that the expires parameter in @SubscriptionState or @Expires header - * in the nua_response() to the SUBSCRIBE overrides the default subscription - * expiration specified by NUTAG_SUB_EXPIRES(). - * - * @sa @RFC3265, NUTAG_REFER_EXPIRES(), @Expires, SIPTAG_EXPIRES(), - * SIPTAG_EXPIRES_STR(), @SubscriptionState, nua_respond(), nua_notifier(), - * #nua_r_subscribe, #nua_i_subscribe, #nua_r_refer, #nua_r_notify, - * #nua_i_notify. - * - * Corresponding tag taking reference parameter is NUTAG_SUB_EXPIRES_REF(). - */ -tag_typedef_t nutag_sub_expires = UINTTAG_TYPEDEF(substate); - -/**@def NUTAG_SUB_EXPIRES_REF(x) - * Reference tag for NUTAG_SUB_EXPIRES(). - */ - - /**@def NUTAG_NEWSUB() * * Send unsolicited NOTIFY request. @@ -1111,17 +1075,17 @@ tag_typedef_t nutag_update_refresh = BOOLTAG_TYPEDEF(update_refresh); * REFER. * * @par Used with - * nua_handle(), nua_respond() \n - * nua_set_params() or nua_set_hparams() \n - * nua_get_params() or nua_get_hparams() + * nua_set_params() \n + * nua_get_params() \n + * nua_set_hparams() \n + * nua_get_hparams() \n * * @par Parameter type * unsigned int * * @par Values - * - default interval in seconds - * - * @sa NUTAG_SUB_EXPIRES() + * @c 0 disable \n + * @c >0 interval in seconds * * Corresponding tag taking reference parameter is NUTAG_REFER_EXPIRES_REF(). */ @@ -1606,9 +1570,6 @@ extern msg_hclass_t sip_route_class[]; * NUTAG_INITIAL_ROUTE_STR() tags, the route set is constructed from them * all. * - * The initial route is inserted into request message before the route - * entries set with SIPTAG_ROUTE() or SIPTAG_ROUTE_STR(). - * * @par Used with * nua_set_params() \n * nua_set_hparams() \n @@ -2775,39 +2736,6 @@ tag_typedef_t nutag_dialog = UINTTAG_TYPEDEF(dialog); * Reference tag for NUTAG_SIP_PARSER(). */ - -/**@def NUTAG_SHUTDOWN_EVENTS(x) - * - * Allow passing of normal events when stack is being shut down. - * - * By default, only #nua_r_shutdown events are passed to application after - * calling nua_shutdown(). If application is interested in nua events during - * shutdown, it should give NUTAG_SHUTDOWN_EVENTS(1) to nua_create() or - * nua_set_params() called before nua_shutdown(). - * - * @par Used with - * nua_create(), nua_set_params(). - * - * @par Parameter type - * int (boolean) - * - * @par Values - * @c 0 False \n - * @c !=0 True - * - * Corresponding tag taking reference parameter is NUTAG_SHUTDOWN_EVENTS_REF(). - * - * @sa nua_shutdown(), nua_destroy(). - * - * @NEW_1_12_9. - */ -tag_typedef_t nutag_shutdown_events = BOOLTAG_TYPEDEF(shutdown_events); - -/**@def NUTAG_SHUTDOWN_EVENTS_REF(x) - * Reference tag for NUTAG_SHUTDOWN_EVENTS(). - */ - - /* ---------------------------------------------------------------------- */ tag_typedef_t nutag_soa_session = PTRTAG_TYPEDEF(soa_session); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h index b8d71c7ca8..01d825e8a5 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h @@ -497,16 +497,12 @@ SOFIAPUBFUN char const *nua_substate_name(enum nua_substate substate); /** Convert string to enum nua_substate. @NEW_1_12_5. */ SOFIAPUBFUN enum nua_substate nua_substate_make(char const *sip_substate); -#define NUTAG_SUB_EXPIRES(x) nutag_sub_expires, tag_uint_v(x) -SOFIAPUBVAR tag_typedef_t nutag_sub_expires; -#define NUTAG_SUB_EXPIRES_REF(x) nutag_sub_expires_ref, tag_uint_vr(&(x)) -SOFIAPUBVAR tag_typedef_t nutag_sub_expires_ref; - #define NUTAG_NEWSUB(x) nutag_newsub, tag_bool_v(x) SOFIAPUBVAR tag_typedef_t nutag_newsub; #define NUTAG_NEWSUB_REF(x) nutag_newsub_ref, tag_bool_vr(&(x)) SOFIAPUBVAR tag_typedef_t nutag_newsub_ref; + #define NUTAG_REFER_EXPIRES(x) nutag_refer_expires, tag_uint_v((x)) SOFIAPUBVAR tag_typedef_t nutag_refer_expires; #define NUTAG_REFER_EXPIRES_REF(x) nutag_refer_expires_ref, tag_uint_vr((&(x))) @@ -573,13 +569,6 @@ SOFIAPUBVAR tag_typedef_t nutag_detect_network_updates; nutag_detect_network_updates_ref, tag_int_vr(&(x)) SOFIAPUBVAR tag_typedef_t nutag_detect_network_updates_ref; -#define NUTAG_SHUTDOWN_EVENTS(x) \ - nutag_shutdown_events, tag_bool_v(x) -SOFIAPUBVAR tag_typedef_t nutag_shutdown_events; -#define NUTAG_SHUTDOWN_EVENTS_REF(x) \ - nutag_shutdown_events_ref, tag_bool_vr(&(x)) -SOFIAPUBVAR tag_typedef_t nutag_shutdown_events_ref; - /* Pass nua handle as tagged argument */ #if SU_INLINE_TAG_CAST su_inline tag_value_t nutag_handle_v(nua_handle_t *v) { return (tag_value_t)v; } diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c index 88c2ae61b1..69f91dffa8 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_cancel_bye.c @@ -1433,9 +1433,6 @@ int test_bye_with_407(struct context *ctx) a_call->sdp = "m=audio 5008 RTP/AVP 8"; c_call->sdp = "m=audio 5010 RTP/AVP 0 8"; - if (!ctx->proxy_tests) - return 0; - /* BYE after receiving 401 A C diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h index 5c67d014d3..1d035fcae1 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua.h @@ -178,10 +178,7 @@ struct context unsigned bit4:1, bit5:1, bit6:1, bit7:1; unsigned :0; } flags; - /* Accross-run state information */ - struct { - unsigned n; - } state; + } a, b, c; struct proxy *p; diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c index 846d104057..6a9f2e1fb7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_nua_params.c @@ -203,7 +203,6 @@ int test_nua_params(struct context *ctx) NUTAG_REFER_EXPIRES(333), NUTAG_REFER_WITH_ID(0), NUTAG_SUBSTATE(nua_substate_pending), - NUTAG_SUB_EXPIRES(3700), NUTAG_KEEPALIVE(66), NUTAG_KEEPALIVE_STREAM(33), @@ -285,7 +284,6 @@ int test_nua_params(struct context *ctx) int auth_cache = -1; unsigned refer_expires = (unsigned)-1; int refer_with_id = -1; - unsigned sub_expires = (unsigned)-1; int substate = -1; sip_allow_t const *allow = NONE; @@ -354,7 +352,6 @@ int test_nua_params(struct context *ctx) NUTAG_REFER_EXPIRES_REF(refer_expires), NUTAG_REFER_WITH_ID_REF(refer_with_id), NUTAG_SUBSTATE_REF(substate), - NUTAG_SUB_EXPIRES_REF(sub_expires), SIPTAG_SUPPORTED_REF(supported), SIPTAG_SUPPORTED_STR_REF(supported_str), @@ -385,7 +382,7 @@ int test_nua_params(struct context *ctx) NUTAG_INSTANCE_REF(instance), TAG_END()); - TEST(n, 51); + TEST(n, 50); TEST_S(sip_header_as_string(tmphome, (void *)from), Alice); TEST_S(from_str, Alice); @@ -419,7 +416,6 @@ int test_nua_params(struct context *ctx) TEST(refer_expires, 333); TEST(refer_with_id, 0); TEST(substate, nua_substate_pending); - TEST(sub_expires, 3700); TEST_S(sip_header_as_string(tmphome, (void *)allow), "OPTIONS, INFO, ACK"); TEST_S(allow_str, "OPTIONS, INFO, ACK"); @@ -496,7 +492,6 @@ int test_nua_params(struct context *ctx) unsigned refer_expires = (unsigned)-1; int refer_with_id = -1; int substate = -1; - unsigned sub_expires = (unsigned)-1; sip_allow_t const *allow = NONE; char const *allow_str = "NONE"; @@ -557,7 +552,6 @@ int test_nua_params(struct context *ctx) NUTAG_PATH_ENABLE_REF(path_enable), NUTAG_AUTH_CACHE_REF(auth_cache), NUTAG_SUBSTATE_REF(substate), - NUTAG_SUB_EXPIRES_REF(sub_expires), SIPTAG_SUPPORTED_REF(supported), SIPTAG_SUPPORTED_STR_REF(supported_str), @@ -613,7 +607,6 @@ int test_nua_params(struct context *ctx) TEST(refer_expires, (unsigned)-1); TEST(refer_with_id, -1); TEST(substate, -1); - TEST(sub_expires, -1); TEST_P(allow, NONE); TEST_S(allow_str, "NONE"); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_ops.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_ops.c index 0c43d9bf40..355d289adb 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_ops.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_ops.c @@ -182,12 +182,6 @@ void print_event(nua_event_t event, ep->name, (void *)nh, nua_event_name(event), phrase, nua_substate_name(t ? t->t_value : 0)); } - else if ((int)event >= nua_i_bye || - event == nua_i_invite || event == nua_i_cancel || - event == nua_i_ack) { - fprintf(stderr, "%s %s.nua(%p): event %s %03d %s\n", timestamp, - ep->name, (void *)nh, nua_event_name(event), status, phrase); - } else if ((int)event >= 0) { fprintf(stderr, "%s %s.nua(%p): event %s %s\n", timestamp, ep->name, (void *)nh, nua_event_name(event), phrase); diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/test_simple.c b/libs/sofia-sip/libsofia-sip-ua/nua/test_simple.c index 4997908f89..020b1f2c4e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/test_simple.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/test_simple.c @@ -45,9 +45,6 @@ extern int accept_request(CONDITION_PARAMS); -int save_until_nth_final_response(CONDITION_PARAMS); -int accept_n_notifys(CONDITION_PARAMS); - int test_message(struct context *ctx) { BEGIN(); @@ -567,47 +564,6 @@ static char const presence_closed[] = "\n"; -int accept_and_notify_twice(CONDITION_PARAMS) -{ - msg_t *with = nua_current_request(nua); - - if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR))) - return 0; - - save_event_in_list(ctx, event, ep, call); - - switch (event) { - case nua_i_subscribe: - if (status < 200) { - NOTIFY(ep, call, nh, - SIPTAG_EVENT(sip->sip_event), - SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), - SIPTAG_PAYLOAD_STR(presence_closed), - NUTAG_SUBSTATE(nua_substate_pending), - TAG_END()); - NOTIFY(ep, call, nh, - SIPTAG_EVENT(sip->sip_event), - SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), - SIPTAG_PAYLOAD_STR(presence_open), - NUTAG_SUBSTATE(nua_substate_active), - TAG_END()); - RESPOND(ep, call, nh, SIP_202_ACCEPTED, - NUTAG_WITH(with), - SIPTAG_EXPIRES_STR("360"), - TAG_END()); - } - return 0; - - case nua_r_notify: - return status >= 200 && - tl_find(tags, nutag_substate)->t_value == nua_substate_active; - - default: - return 0; - } -} - - int accept_and_notify(CONDITION_PARAMS) { msg_t *with = nua_current_request(nua); @@ -624,14 +580,12 @@ int accept_and_notify(CONDITION_PARAMS) NUTAG_WITH(with), SIPTAG_EXPIRES_STR("360"), TAG_END()); - NOTIFY(ep, call, nh, SIPTAG_EVENT(sip->sip_event), SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), SIPTAG_PAYLOAD_STR(presence_closed), NUTAG_SUBSTATE(nua_substate_pending), TAG_END()); - } return 0; @@ -643,31 +597,6 @@ int accept_and_notify(CONDITION_PARAMS) } } -int save_and_notify(CONDITION_PARAMS) -{ - if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR))) - return 0; - - save_event_in_list(ctx, event, ep, call); - - switch (event) { - case nua_i_subscribe: - NOTIFY(ep, call, nh, - SIPTAG_EVENT(sip->sip_event), - SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), - SIPTAG_PAYLOAD_STR(presence_closed), - NUTAG_SUBSTATE(nua_substate_active), - TAG_END()); - return 0; - - case nua_r_notify: - return status >= 200; - - default: - return 0; - } -} - extern int save_until_notified_and_responded(CONDITION_PARAMS); extern int save_until_notified(CONDITION_PARAMS); @@ -677,7 +606,7 @@ int test_subscribe_notify(struct context *ctx) struct endpoint *a = &ctx->a, *b = &ctx->b; struct call *a_call = a->call, *b_call = b->call; - struct event *e, *en1, *en2, *es; + struct event *e; sip_t const *sip; tagi_t const *n_tags, *r_tags; @@ -691,47 +620,44 @@ int test_subscribe_notify(struct context *ctx) SUBSCRIBE(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url), SIPTAG_EVENT_STR("presence"), - SIPTAG_EXPIRES_STR("333"), SIPTAG_ACCEPT_STR("application/xpidf, application/pidf+xml"), TAG_END()); run_ab_until(ctx, -1, save_until_notified_and_responded, - -1, accept_and_notify_twice); + -1, accept_and_notify); /* Client events: - nua_subscribe(), nua_i_notify/nua_r_subscribe/nua_i_notify + nua_subscribe(), nua_i_notify/nua_r_subscribe */ - for (en1 = en2 = es = NULL, e = a->events->head; e; e = e->next) { - if (en1 == NULL && e->data->e_event == nua_i_notify) - en1 = e; - else if (en2 == NULL && e->data->e_event == nua_i_notify) - en2 = e; - else if (e->data->e_event == nua_r_subscribe) - es = e; - else - TEST_1(!e); + TEST_1(e = a->events->head); + if (e->data->e_event == nua_i_notify) { + TEST_E(e->data->e_event, nua_i_notify); + TEST_1(sip = sip_object(e->data->e_msg)); + n_tags = e->data->e_tags; + TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_subscribe); + r_tags = e->data->e_tags; + TEST_1(tl_find(r_tags, nutag_substate)); + TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_pending); + } + else { + TEST_E(e->data->e_event, nua_r_subscribe); + TEST(e->data->e_status, 202); + r_tags = e->data->e_tags; + TEST_1(tl_find(r_tags, nutag_substate)); + TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_embryonic); + TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); + TEST_1(sip = sip_object(e->data->e_msg)); + n_tags = e->data->e_tags; } - - TEST_1(e = en1); - TEST_E(e->data->e_event, nua_i_notify); - TEST_1(tl_find(e->data->e_tags, nutag_substate)); - TEST(tl_find(e->data->e_tags, nutag_substate)->t_value, nua_substate_pending); - TEST_1(sip = sip_object(e->data->e_msg)); TEST_1(sip->sip_event); TEST_S(sip->sip_event->o_type, "presence"); TEST_1(sip->sip_content_type); TEST_S(sip->sip_content_type->c_type, "application/pidf+xml"); TEST_1(sip->sip_subscription_state); TEST_S(sip->sip_subscription_state->ss_substate, "pending"); TEST_1(sip->sip_subscription_state->ss_expires); - - TEST_1(e = es); TEST_E(e->data->e_event, nua_r_subscribe); - TEST_1(e->data->e_status == 202 || e->data->e_status == 200); - TEST_1(tl_find(e->data->e_tags, nutag_substate)); - TEST(tl_find(e->data->e_tags, nutag_substate)->t_value, nua_substate_pending); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_expires); - TEST_1(sip->sip_expires->ex_delta <= 333); - + TEST_1(tl_find(n_tags, nutag_substate)); + TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_pending); + TEST_1(!e->next); free_events_in_list(ctx, a->events); /* Server events: nua_i_subscribe, nua_r_notify */ @@ -805,80 +731,6 @@ int test_subscribe_notify(struct context *ctx) /* ---------------------------------------------------------------------- */ -/* Re-SUBSCRIBE - - A B - | | - |<------NOTIFY-------| - |-------200 OK------>| - | | -*/ - if (print_headings) - printf("TEST NUA-11.4.3: re-SUBSCRIBE\n"); - - /* Set default expiration time */ - nua_set_hparams(b_call->nh, NUTAG_SUB_EXPIRES(365), TAG_END()); - run_b_until(ctx, nua_r_set_params, until_final_response); - - SUBSCRIBE(a, a_call, a_call->nh, NUTAG_URL(b->contact->m_url), - SIPTAG_EVENT_STR("presence"), - SIPTAG_EXPIRES_STR("3600"), - SIPTAG_ACCEPT_STR("application/xpidf, application/pidf+xml"), - TAG_END()); - - run_ab_until(ctx, -1, save_until_notified_and_responded, - -1, save_until_final_response); - - /* Client events: - nua_subscribe(), nua_i_notify/nua_r_subscribe - */ - for (en1 = en2 = es = NULL, e = a->events->head; e; e = e->next) { - if (en1 == NULL && e->data->e_event == nua_i_notify) - en1 = e; - else if (e->data->e_event == nua_r_subscribe) - es = e; - else - TEST_1(!e); - } - TEST_1(e = en1); - TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_event); TEST_S(sip->sip_event->o_type, "presence"); - TEST_1(sip->sip_content_type); - TEST_S(sip->sip_content_type->c_type, "application/pidf+xml"); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - TEST_1(sip->sip_subscription_state->ss_expires); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - - TEST_1(e = es); TEST_E(e->data->e_event, nua_r_subscribe); - TEST_1(tl_find(e->data->e_tags, nutag_substate)); - TEST(tl_find(e->data->e_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_expires); - TEST_1(sip->sip_expires->ex_delta <= 365); - - free_events_in_list(ctx, a->events); - - /* Server events: nua_i_subscribe, nua_r_notify */ - TEST_1(e = b->events->head); - TEST_E(e->data->e_event, nua_i_subscribe); - TEST_E(e->data->e_status, 100); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_active); - - free_events_in_list(ctx, b->events); - - if (print_headings) - printf("TEST NUA-11.4.3: PASSED\n"); - - /* ---------------------------------------------------------------------- */ - /* un-SUBSCRIBE A B @@ -890,7 +742,7 @@ int test_subscribe_notify(struct context *ctx) | | */ if (print_headings) - printf("TEST NUA-11.4.4: un-SUBSCRIBE\n"); + printf("TEST NUA-11.4.3: un-SUBSCRIBE\n"); UNSUBSCRIBE(a, a_call, a_call->nh, TAG_END()); @@ -900,35 +752,31 @@ int test_subscribe_notify(struct context *ctx) /* Client events: nua_unsubscribe(), nua_i_notify/nua_r_unsubscribe */ - for (en1 = en2 = es = NULL, e = a->events->head; e; e = e->next) { - if (en1 == NULL && e->data->e_event == nua_i_notify) - en1 = e; - else if (e->data->e_event == nua_r_unsubscribe) - es = e; - else - TEST_1(!e); - } - if (en1) { - TEST_1(e = en1); TEST_E(e->data->e_event, nua_i_notify); + TEST_1(e = a->events->head); + if (e->data->e_event == nua_i_notify) { + TEST_E(e->data->e_event, nua_i_notify); + n_tags = e->data->e_tags; TEST_1(sip = sip_object(e->data->e_msg)); TEST_1(sip->sip_event); TEST_1(sip->sip_subscription_state); TEST_S(sip->sip_subscription_state->ss_substate, "terminated"); TEST_1(!sip->sip_subscription_state->ss_expires); - n_tags = e->data->e_tags; TEST_1(tl_find(n_tags, nutag_substate)); TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_terminated); + TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_unsubscribe); + TEST(e->data->e_status, 200); + r_tags = e->data->e_tags; + TEST_1(tl_find(r_tags, nutag_substate)); + TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated); } - - TEST_1(e = es); TEST_E(e->data->e_event, nua_r_unsubscribe); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_expires); - TEST_1(sip->sip_expires->ex_delta == 0); - + else { + TEST_E(e->data->e_event, nua_r_unsubscribe); + TEST(e->data->e_status, 200); + r_tags = e->data->e_tags; + TEST_1(tl_find(r_tags, nutag_substate)); + TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated); + } + TEST_1(!e->next); free_events_in_list(ctx, a->events); /* Notifier events: nua_r_notify */ @@ -951,7 +799,7 @@ int test_subscribe_notify(struct context *ctx) nua_handle_destroy(b_call->nh), b_call->nh = NULL; if (print_headings) - printf("TEST NUA-11.4.4: PASSED\n"); + printf("TEST NUA-11.4.3: PASSED\n"); if (print_headings) printf("TEST NUA-11.4: PASSED\n"); @@ -977,7 +825,7 @@ int test_subscribe_notify_graceful(struct context *ctx) struct endpoint *a = &ctx->a, *b = &ctx->b; struct call *a_call = a->call, *b_call = b->call; - struct event *e, *en1, *en2, *es; + struct event *e; sip_t const *sip; tagi_t const *n_tags, *r_tags; struct nat_filter *f; @@ -998,33 +846,35 @@ int test_subscribe_notify_graceful(struct context *ctx) /* Client events: nua_subscribe(), nua_i_notify/nua_r_subscribe */ - for (en1 = en2 = es = NULL, e = a->events->head; e; e = e->next) { - if (en1 == NULL && e->data->e_event == nua_i_notify) - en1 = e; - else if (es == NULL && e->data->e_event == nua_r_subscribe) - es = e; - else - TEST_1(!e); + TEST_1(e = a->events->head); + if (e->data->e_event == nua_i_notify) { + TEST_E(e->data->e_event, nua_i_notify); + TEST_1(sip = sip_object(e->data->e_msg)); + n_tags = e->data->e_tags; + TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_subscribe); + r_tags = e->data->e_tags; + TEST_1(tl_find(r_tags, nutag_substate)); + TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_pending); + } + else { + TEST_E(e->data->e_event, nua_r_subscribe); + TEST(e->data->e_status, 202); + r_tags = e->data->e_tags; + TEST_1(tl_find(r_tags, nutag_substate)); + TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_embryonic); + TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); + TEST_1(sip = sip_object(e->data->e_msg)); + n_tags = e->data->e_tags; } - TEST_1(e = en1); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); TEST_1(sip->sip_event); TEST_S(sip->sip_event->o_type, "presence"); TEST_1(sip->sip_content_type); TEST_S(sip->sip_content_type->c_type, "application/pidf+xml"); TEST_1(sip->sip_subscription_state); TEST_S(sip->sip_subscription_state->ss_substate, "pending"); TEST_1(sip->sip_subscription_state->ss_expires); - n_tags = e->data->e_tags; TEST_1(tl_find(n_tags, nutag_substate)); TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_pending); - - TEST_1(e = es); TEST_E(e->data->e_event, nua_r_subscribe); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - if (es == a->events->head) - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_embryonic); - else - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_pending); + TEST_1(!e->next); free_events_in_list(ctx, a->events); /* Server events: nua_i_subscribe, nua_r_notify */ @@ -1161,6 +1011,7 @@ int save_until_notify_responded_twice(CONDITION_PARAMS) return ep->flags.bit0 && ep->flags.bit1; } + /* ---------------------------------------------------------------------- */ /* Unsolicited NOTIFY */ @@ -1177,8 +1028,6 @@ int test_newsub_notify(struct context *ctx) sip_call_id_t *i; tagi_t const *n_tags, *r_tags; -#if 0 - if (print_headings) printf("TEST NUA-11.7.1: rejecting NOTIFY without subscription locally\n"); @@ -1312,298 +1161,6 @@ int test_newsub_notify(struct context *ctx) nua_handle_destroy(a_call->nh), a_call->nh = NULL; nua_handle_destroy(b_call->nh), b_call->nh = NULL; -#else - (void)i; - nua_set_params(b->nua, NUTAG_APPL_METHOD("NOTIFY"), TAG_END()); - run_b_until(ctx, nua_r_set_params, until_final_response); -#endif - - /* ---------------------------------------------------------------------- */ - - if (print_headings) - printf("TEST NUA-11.7.4: multiple unsolicited NOTIFYs\n"); - - TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END())); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_EXPIRES_STR("10"), - SIPTAG_SUBJECT_STR("NUA-11.7.4aa"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: no"), - TAG_END()); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("active; expires=333"), - SIPTAG_SUBJECT_STR("NUA-11.7.4a"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: no"), - TAG_END()); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("active; expires=3000"), - SIPTAG_SUBJECT_STR("NUA-11.7.4b"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: yes"), - TAG_END()); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("terminated"), - SIPTAG_SUBJECT_STR("NUA-11.7.4c"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: yes"), - TAG_END()); - - a->state.n = 4; - b->state.n = 4; - - run_ab_until(ctx, -1, save_until_nth_final_response, - -1, accept_n_notifys); - - /* Notifier events: nua_r_notify nua_r_notify */ - TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated); - - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated); - TEST_1(!e->next); - - /* subscriber events: - nua_i_notify - */ - TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "terminated"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_terminated); - - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "terminated"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_terminated); - TEST_1(!e->next); - - free_events_in_list(ctx, a->events); - free_events_in_list(ctx, b->events); - - nua_handle_destroy(a_call->nh), a_call->nh = NULL; - nua_handle_destroy(b_call->nh), b_call->nh = NULL; - - if (print_headings) - printf("TEST NUA-11.7.4: PASSED\n"); - - /* ---------------------------------------------------------------------- */ - - if (print_headings) - printf("TEST NUA-11.7.5: multiple unsolicited NOTIFYs\n"); - - TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END())); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("active; expires=333"), - SIPTAG_SUBJECT_STR("NUA-11.7.5a"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: no"), - TAG_END()); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("active; expires=3000"), - SIPTAG_SUBJECT_STR("NUA-11.7.5b"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: yes"), - TAG_END()); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("terminated"), - SIPTAG_SUBJECT_STR("NUA-11.7.5c"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: yes"), - TAG_END()); - - a->state.n = 3; - b->state.n = 3; - - run_ab_until(ctx, -1, save_until_nth_final_response, - -1, accept_n_notifys); - - /* Notifier events: nua_r_notify nua_r_notify */ - TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_notify); - TEST(e->data->e_status, 200); - r_tags = e->data->e_tags; - TEST_1(tl_find(r_tags, nutag_substate)); - TEST(tl_find(r_tags, nutag_substate)->t_value, nua_substate_terminated); - TEST_1(!e->next); - - /* subscriber events: - nua_i_notify - */ - TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "terminated"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_terminated); - TEST_1(!e->next); - - free_events_in_list(ctx, a->events); - free_events_in_list(ctx, b->events); - - nua_handle_destroy(a_call->nh), a_call->nh = NULL; - nua_handle_destroy(b_call->nh), b_call->nh = NULL; - - if (print_headings) - printf("TEST NUA-11.7.5: PASSED\n"); - - /* ---------------------------------------------------------------------- */ - -#if 0 - - if (print_headings) - printf("TEST NUA-11.7.6: unsolicited NOTIFY handle destroyed\n"); - - TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END())); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("active; expires=333"), - SIPTAG_SUBJECT_STR("NUA-11.7.6a"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: no"), - TAG_END()); - - NOTIFY(a, a_call, a_call->nh, - NUTAG_URL(b->contact->m_url), - NUTAG_NEWSUB(1), - SIPTAG_SUBSCRIPTION_STATE_STR("active; expires=3000"), - SIPTAG_SUBJECT_STR("NUA-11.7.6b"), - SIPTAG_EVENT_STR("message-summary"), - SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), - SIPTAG_PAYLOAD_STR("Messages-Waiting: yes"), - TAG_END()); - - nua_handle_destroy(a_call->nh), a_call->nh = NULL; - - a->state.n = 3; - b->state.n = 3; - - run_b_until(ctx, -1, accept_n_notifys); - - /* subscriber events: - nua_i_notify - */ - TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "active"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_active); - TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_notify); - TEST_1(sip = sip_object(e->data->e_msg)); - TEST_1(sip->sip_subscription_state); - TEST_S(sip->sip_subscription_state->ss_substate, "terminated"); - n_tags = e->data->e_tags; - TEST_1(tl_find(n_tags, nutag_substate)); - TEST(tl_find(n_tags, nutag_substate)->t_value, nua_substate_terminated); - TEST_1(!e->next); - - free_events_in_list(ctx, b->events); - - if (print_headings) - printf("TEST NUA-11.7.6: PASSED\n"); - - nua_handle_destroy(b_call->nh), b_call->nh = NULL; - -#endif - if (print_headings) printf("TEST NUA-11.7: PASSED\n"); @@ -1626,50 +1183,6 @@ int accept_notify(CONDITION_PARAMS) return event == nua_i_notify; } -int save_until_nth_final_response(CONDITION_PARAMS) -{ - save_event_in_list(ctx, event, ep, call); - - if (nua_r_set_params <= event && event < nua_i_network_changed - && status >= 200) { - if (ep->state.n > 0) - ep->state.n--; - return ep->state.n == 0; - } - - return 0; -} - -int accept_n_notifys(CONDITION_PARAMS) -{ - tagi_t const *substate = tl_find(tags, nutag_substate); - - if (event == nua_i_notify && status < 200) - RESPOND(ep, call, nh, SIP_200_OK, - NUTAG_WITH_THIS(ep->nua), - TAG_END()); - - save_event_in_list(ctx, event, ep, call); - - if (event != nua_i_notify) - return 0; - - if (ep->state.n > 0) - ep->state.n--; - - if (ep->state.n == 0) - return 1; - - if (substate && substate->t_value == nua_substate_terminated) { - if (call && call->nh == nh) { - call->nh = NULL; - nua_handle_destroy(nh); - } - } - - return 0; -} - /* ======================================================================== */ int save_until_subscription_terminated(CONDITION_PARAMS); @@ -1823,8 +1336,8 @@ int accept_subscription_until_terminated(CONDITION_PARAMS) int test_simple(struct context *ctx) { - return 0 - || test_message(ctx) + return + test_message(ctx) || test_publish(ctx) || test_subscribe_notify(ctx) || test_subscribe_notify_graceful(ctx)