📄 nua_stack.c
字号:
nua_stack_notifier(nua_t *, nua_handle_t *, nua_event_t, tagi_t const *), nua_stack_terminate(nua_t *, nua_handle_t *, nua_event_t, tagi_t const *);int nh_notifier_shutdown(nua_handle_t *nh, nea_event_t *ev, tag_type_t t, tag_value_t v, ...);/** Send an event to the application. */int nua_stack_event(nua_t *nua, nua_handle_t *nh, msg_t *msg, nua_event_t event, int status, char const *phrase, tag_type_t tag, tag_value_t value, ...){ su_msg_r sumsg = SU_MSG_R_INIT; ta_list ta; int e_len, len, xtra, p_len; enter; if (nua_log->log_level >= 5) { char const *name = nua_event_name(event) + 4; char const *p = phrase ? phrase : ""; if (status == 0) SU_DEBUG_5(("nua(%p): %s %s\n", nh, name, p)); else SU_DEBUG_5(("nua(%p): %s %u %s\n", nh, name, status, p)); } if (event == nua_r_destroy) { if (msg) msg_destroy(msg); if (status >= 200) { nh_destroy(nua, nh); } return event; } if (event > nua_r_method || (nh && !nh->nh_valid) || (nua->nua_shutdown && event != nua_r_shutdown)) { if (msg) msg_destroy(msg); return event; } ta_start(ta, tag, value); e_len = offsetof(event_t, e_tags); len = tl_len(ta_args(ta)); xtra = tl_xtra(ta_args(ta), len); p_len = phrase ? strlen(phrase) + 1 : 1; if (su_msg_create(sumsg, nua->nua_client, nua->nua_server, nua_event, e_len + len + xtra + p_len) == 0) { event_t *e = su_msg_data(sumsg); tagi_t *t = e->e_tags, *t_end = (tagi_t *)((char *)t + len); void *b = t_end, *end = (char *)b + xtra; t = tl_dup(t, ta_args(ta), &b); assert(t == t_end); assert(b == end); e->e_event = event; e->e_nh = nh ? nua_handle_ref(nh) : nua->nua_dhandle; e->e_status = status; e->e_phrase = strcpy(end, phrase ? phrase : ""); e->e_msg = msg; if (su_msg_send(sumsg) != 0) nua_handle_unref(nh); } ta_end(ta); return event;}/* ---------------------------------------------------------------------- * Post signal to stack itself */void nua_stack_post_signal(nua_handle_t *nh, nua_event_t event, tag_type_t tag, tag_value_t value, ...){ ta_list ta; ta_start(ta, tag, value); nua_signal((nh)->nh_nua, nh, NULL, 1, event, 0, NULL, ta_tags(ta)); ta_end(ta);}/* ---------------------------------------------------------------------- * Receiving events from client */void nua_stack_signal(nua_t *nua, su_msg_r msg, nua_event_data_t *e){ nua_handle_t *nh = e->e_nh; tagi_t *tags = e->e_tags; if (nh) { if (!nh->nh_prev) nh_append(nua, nh); if (!nh->nh_ref_by_stack) { nh->nh_ref_by_stack = 1; nua_handle_ref(nh); } } if (nua_log->log_level >= 5) { char const *name = nua_event_name(e->e_event); if (e->e_status == 0) SU_DEBUG_5(("nua(%p): signal %s\n", nh, name + 4)); else SU_DEBUG_5(("nua(%p): signal %s %u %s\n", nh, name + 4, e->e_status, e->e_phrase ? e->e_phrase : "")); } su_msg_save(nua->nua_signal, msg); if (nua->nua_shutdown && !e->e_always) { /* Shutting down */ nua_stack_event(nua, nh, NULL, e->e_event, 500, "Stack is going down", TAG_END()); } else switch (e->e_event) { case nua_r_get_params: nua_stack_get_params(nua, nh ? nh : nua->nua_dhandle, e->e_event, tags); break; case nua_r_set_params: nua_stack_set_params(nua, nh ? nh : nua->nua_dhandle, e->e_event, tags); break; case nua_r_shutdown: nua_stack_shutdown(nua); break; case nua_r_register: case nua_r_unregister: nua_stack_register(nua, nh, e->e_event, tags); break; case nua_r_invite: nua_stack_invite(nua, nh, e->e_event, tags); break; case nua_r_cancel: nua_stack_cancel(nua, nh, e->e_event, tags); break; case nua_r_bye: nua_stack_bye(nua, nh, e->e_event, tags); break; case nua_r_options: nua_stack_options(nua, nh, e->e_event, tags); break; case nua_r_refer: nua_stack_refer(nua, nh, e->e_event, tags); break; case nua_r_publish: case nua_r_unpublish: nua_stack_publish(nua, nh, e->e_event, tags); break; case nua_r_info: nua_stack_info(nua, nh, e->e_event, tags); break; case nua_r_update: nua_stack_update(nua, nh, e->e_event, tags); break; case nua_r_message: nua_stack_message(nua, nh, e->e_event, tags); break; case nua_r_subscribe: case nua_r_unsubscribe: nua_stack_subscribe(nua, nh, e->e_event, tags); break; case nua_r_notify: nua_stack_notify(nua, nh, e->e_event, tags); break; case nua_r_notifier: nua_stack_notifier(nua, nh, e->e_event, tags); break; case nua_r_terminate: nua_stack_terminate(nua, nh, e->e_event, tags); break; case nua_r_method: nua_stack_method(nua, nh, e->e_event, tags); break; case nua_r_authenticate: nua_stack_authenticate(nua, nh, e->e_event, tags); break; case nua_r_authorize: nua_stack_authorize(nua, nh, e->e_event, tags); break; case nua_r_ack: nua_stack_ack(nua, nh, e->e_event, tags); break; case nua_r_respond: nua_stack_respond(nua, nh, e->e_status, e->e_phrase, tags); break; case nua_r_destroy: nua_stack_destroy_handle(nua, nh, tags); break; default: break; } if (su_msg_is_non_null(nua->nua_signal)) su_msg_destroy(nua->nua_signal); if (nh != nua->nua_dhandle) nua_handle_unref(nh);}/* ====================================================================== */static int nh_call_pending(nua_handle_t *nh, sip_time_t time);/** Timer routine. * * Go through all active handles and execute pending tasks */void nua_stack_timer(nua_t *nua, su_timer_t *t, su_timer_arg_t *a){ nua_handle_t *nh, *nh_next; sip_time_t now = sip_now(); su_timer_set(t, nua_stack_timer, a); if (nua->nua_shutdown) { nua_stack_shutdown(nua); return; } for (nh = nua->nua_handles; nh; nh = nh_next) { nh_next = nh->nh_next; nh_call_pending(nh, now); }}staticint nh_call_pending(nua_handle_t *nh, sip_time_t now){ nua_dialog_usage_t *du; sip_time_t next = now + NUA_STACK_TIMER_INTERVAL / 1000; for (du = nh->nh_ds->ds_usage; du; du = du->du_next) { if (!du->du_pending) continue; if (now == 0 || (du->du_refresh && du->du_refresh < next)) break; } if (du == NULL) return 0; nua_handle_ref(nh); while (du) { nh_pending_f *pending = du->du_pending; nua_dialog_usage_t *du_next = du->du_next; du->du_pending = NULL; pending(nh, du, now); if (du_next == NULL) break; for (du = nh->nh_ds->ds_usage; du; du = du->du_next) if (du == du_next) break; for (; du; du = du->du_next) { if (!du->du_pending) continue; if (now == 0 || (du->du_refresh && du->du_refresh < next)) break; } } nua_handle_unref(nh); return 1;}/* ====================================================================== *//** Shut down stack. */void nua_stack_shutdown(nua_t *nua){ nua_handle_t *nh, *nh_next; int busy = 0; sip_time_t now = sip_now(); int status; char const *phrase; struct nua_session_state *ss; enter; if (!nua->nua_shutdown) nua->nua_shutdown = now; for (nh = nua->nua_handles; nh; nh = nh_next) { nh_next = nh->nh_next; ss = nh->nh_ss; if (ss->ss_srequest->sr_respond) { ss->ss_srequest->sr_respond(nua, nh, SIP_410_GONE, NULL); busy++; } busy += nh_call_pending(nh, 0); if (nh->nh_soa) { soa_destroy(nh->nh_soa), nh->nh_soa = NULL; } if (nh->nh_cr->cr_orq || nh->nh_ss->ss_crequest->cr_orq) busy++; if (nh_notifier_shutdown(nh, NULL, NEATAG_REASON("noresource"), TAG_END())) busy++; } if (!busy) SET_STATUS(200, "Shutdown successful"); else if (now == nua->nua_shutdown) SET_STATUS(100, "Shutdown started"); else if (now - nua->nua_shutdown < 30) SET_STATUS(101, "Shutdown in progress"); else SET_STATUS(500, "Shutdown timeout"); if (status >= 200) { su_timer_destroy(nua->nua_timer), nua->nua_timer = NULL; nta_agent_destroy(nua->nua_nta), nua->nua_nta = NULL; } nua_stack_event(nua, NULL, NULL, nua_r_shutdown, status, phrase, TAG_END());}/* ---------------------------------------------------------------------- * Parameters */#include <sofia-sip/msg_parser.h>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; nua_handle_preferences_t nhp[1], *ohp = nh->nh_prefs; nua_handle_preferences_t const *dnhp = dnh->nh_prefs; su_home_t tmphome[1] = { SU_HOME_INIT(tmphome) }; unsigned retry_count = NHP_GET(ohp, dnhp, retry_count); unsigned max_subscriptions = NHP_GET(ohp, dnhp, max_subscriptions); int invite_enable = NHP_GET(ohp, dnhp, invite_enable); int auto_alert = NHP_GET(ohp, dnhp, auto_alert); int early_media = NHP_GET(ohp, dnhp, early_media); int auto_answer = NHP_GET(ohp, dnhp, auto_answer); int auto_ack = NHP_GET(ohp, dnhp, auto_ack); unsigned invite_timeout = NHP_GET(ohp, dnhp, invite_timeout); unsigned session_timer = NHP_GET(ohp, dnhp, session_timer); unsigned min_se = NHP_GET(ohp, dnhp, min_se); int refresher = NHP_GET(ohp, dnhp, refresher); int update_refresh = NHP_GET(ohp, dnhp, update_refresh); int message_enable = NHP_GET(ohp, dnhp, message_enable); int win_messenger_enable = NHP_GET(ohp, dnhp, win_messenger_enable); int message_auto_respond = NHP_GET(ohp, dnhp, message_auto_respond); int callee_caps = NHP_GET(ohp, dnhp, callee_caps); int media_features = NHP_GET(ohp, dnhp, media_features); int service_route_enable = NHP_GET(ohp, dnhp, service_route_enable); int path_enable = NHP_GET(ohp, dnhp, path_enable); int substate = NHP_GET(ohp, dnhp, substate); sip_allow_t const *allow = NONE; char const *allow_str = NONE; char const *allowing = NULL; sip_supported_t const *supported = NONE; char const *supported_str = NONE; sip_user_agent_t const *user_agent = NONE; char const *user_agent_str = NONE, *ua_name = NONE; sip_organization_t const *organization = NONE; char const *organization_str = NONE; url_string_t const *registrar = NONE; sip_from_t const *from = NONE; char const *from_str = NONE;#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;#endif int n; enter; if (nh == dnh) if (nta_agent_set_params(nua->nua_nta, TAG_NEXT(tags)) < 0) return UA_EVENT2(e, 400, "Error setting NTA parameters"), -1; if (nh->nh_soa && soa_set_params(nh->nh_soa, TAG_NEXT(tags)) < 0) return UA_EVENT2(e, 400, "Error setting SOA parameters"), -1; n = tl_gets(tags, NUTAG_RETRY_COUNT_REF(retry_count), NUTAG_MAX_SUBSCRIPTIONS_REF(max_subscriptions), NUTAG_ENABLEINVITE_REF(invite_enable), NUTAG_AUTOALERT_REF(auto_alert), NUTAG_EARLY_MEDIA_REF(early_media), NUTAG_AUTOANSWER_REF(auto_answer), NUTAG_AUTOACK_REF(auto_ack), NUTAG_INVITE_TIMER_REF(invite_timeout), NUTAG_SESSION_TIMER_REF(session_timer), NUTAG_MIN_SE_REF(min_se), NUTAG_SESSION_REFRESHER_REF(refresher), NUTAG_UPDATE_REFRESH_REF(update_refresh), NUTAG_ENABLEMESSAGE_REF(message_enable), NUTAG_ENABLEMESSENGER_REF(win_messenger_enable), /* NUTAG_MESSAGE_AUTOANSWER(message_auto_respond), */ NUTAG_CALLEE_CAPS_REF(callee_caps), NUTAG_MEDIA_FEATURES_REF(media_features), NUTAG_SERVICE_ROUTE_ENABLE_REF(service_route_enable), NUTAG_PATH_ENABLE_REF(path_enable), NUTAG_SUBSTATE_REF(substate), SIPTAG_SUPPORTED_REF(supported), SIPTAG_SUPPORTED_STR_REF(supported_str), SIPTAG_ALLOW_REF(allow), SIPTAG_ALLOW_STR_REF(allow_str), NUTAG_ALLOW_REF(allowing), SIPTAG_USER_AGENT_REF(user_agent), SIPTAG_USER_AGENT_STR_REF(user_agent_str), NUTAG_USER_AGENT_REF(ua_name), SIPTAG_ORGANIZATION_REF(organization), SIPTAG_ORGANIZATION_STR_REF(organization_str), TAG_IF(nh != dnh, TAG_END()), NUTAG_REGISTRAR_REF(registrar), SIPTAG_FROM_REF(from), SIPTAG_FROM_STR_REF(from_str),#if HAVE_SOFIA_SMIME 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),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -