📄 nua_register.c
字号:
char const *m_username; char const *m_params; url_t const *u; if (nr->nr_by_stack && nr->nr_ob) { m = outbound_dialog_gruu(nr->nr_ob); if (m) return msg_header_add_dup(msg, (msg_pub_t *)sip, (void const *)m); m = outbound_dialog_contact(nr->nr_ob); } if (m == NULL) m = nr->nr_contact; if (!m) return -1; u = m->m_url; if (NH_PISSET(nh, m_display)) m_display = NH_PGET(nh, m_display); else m_display = m->m_display; if (NH_PISSET(nh, m_username)) m_username = NH_PGET(nh, m_username); else m_username = m->m_url->url_user; if (NH_PISSET(nh, m_params)) { m_params = NH_PGET(nh, m_params); if (u->url_params && m_params && strstr(u->url_params, m_params) == 0) m_params = NULL; } else m_params = NULL; m = sip_contact_format(msg_home(msg), "%s<%s:%s%s%s%s%s%s%s%s%s>", m_display ? m_display : "", u->url_scheme, m_username ? m_username : "", m_username ? "@" : "", u->url_host, u->url_port ? ":" : "", u->url_port ? u->url_port : "", u->url_params ? ";" : "", u->url_params ? u->url_params : "", m_params ? ";" : "", m_params ? m_params : ""); if (msg_header_insert(msg, (msg_pub_t *)sip, (void *)m) < 0) return -1; } if (add_service_route && !sip->sip_status) { sip_route_t const *sr = nua_registration_route(nr); if (msg_header_add_dup(msg, (msg_pub_t *)sip, (void const *)sr) < 0) return -1; } return 0;}/** Add a registration to list of contacts */int nua_registration_add(nua_registration_t **list, nua_registration_t *nr){ assert(list && nr); if (nr->nr_list == NULL) { nua_registration_t *next = *list; if (next) next->nr_prev = &nr->nr_next; nr->nr_next = next, nr->nr_prev = list, nr->nr_list = list; *list = nr; } return 0;}/** Remove from list of registrations */void nua_registration_remove(nua_registration_t *nr){ if ((*nr->nr_prev = nr->nr_next)) nr->nr_next->nr_prev = nr->nr_prev; nr->nr_next = NULL, nr->nr_prev = NULL, nr->nr_list = NULL;}/** Set address-of-record. */int nua_registration_set_aor(su_home_t *home, nua_registration_t *nr, sip_from_t const *aor){ sip_from_t *new_aor, *old_aor; if (!home || !nr || !aor) return -1; new_aor = sip_from_dup(home, aor); if (!new_aor) return -1; old_aor = nr->nr_aor; nr->nr_aor = new_aor; msg_header_free(home, (void *)old_aor); return 0;}/** Set contact. */int nua_registration_set_contact(nua_handle_t *nh, nua_registration_t *nr, sip_contact_t const *application_contact, int terminating){ sip_contact_t *m = NULL, *previous; url_t *uri; if (!nh || !nr) return -1; uri = nr->nr_aor ? nr->nr_aor->a_url : NULL; previous = nr->nr_contact; if (application_contact) { m = sip_contact_dup(nh->nh_home, application_contact); } else if (terminating && nr->nr_contact) { return 0; } else { nua_registration_t *nr0; nr0 = nua_registration_by_aor(*nr->nr_list, NULL, uri, 1); if (nr0 && nr0->nr_via) { char const *tport = nr0->nr_via->v_next ? NULL : nr0->nr_via->v_protocol; m = nua_handle_contact_by_via(nh, nh->nh_home, 0, nr0->nr_via, tport, NULL); } } if (!m) return -1; nr->nr_contact = m; *nr->nr_dcontact = *m, nr->nr_dcontact->m_params = NULL; nr->nr_ip4 = host_is_ip4_address(m->m_url->url_host); nr->nr_ip6 = !nr->nr_ip4 && host_is_ip6_reference(m->m_url->url_host); nr->nr_by_stack = !application_contact; msg_header_free(nh->nh_home, (void *)previous); return 0;}/** Mark registration as ready */void nua_registration_set_ready(nua_registration_t *nr, int ready){ if (nr) { assert(!ready || nr->nr_contact); nr->nr_ready = ready; }}/** @internal Hook for processing incoming request by registration. * * This is used for keepalive/validate OPTIONS. */int nua_registration_process_request(nua_registration_t *list, nta_incoming_t *irq, sip_t const *sip){ sip_call_id_t *i; nua_registration_t *nr; if (!outbound_targeted_request(sip)) return 0; /* Process by outbound... */ i = sip->sip_call_id; for (nr = list; nr; nr = nr->nr_next) { outbound_t *ob = nr->nr_ob; if (ob) if (outbound_process_request(ob, irq, sip)) return 501; /* Just in case */ } return 481; /* Call/Transaction does not exist */}/** Outbound requests us to refresh registration */static int nua_stack_outbound_refresh(nua_handle_t *nh, outbound_t *ob){ nua_dialog_state_t *ds = nh->nh_ds; nua_dialog_usage_t *du; du = nua_dialog_usage_get(ds, nua_register_usage, NULL); if (du) nua_dialog_usage_refresh(nh, ds, du, 1); return 0;}/** @NUA_EVENT nua_i_outbound * * Status from outbound engine. * * @param status SIP status code or NUA status code (>= 900) * describing the outbound state * @param phrase a short textual description of @a status code * @param nh operation handle associated with the outbound engine * @param hmagic application context associated with the handle * @param sip NULL or response message to an keepalive message or * registration probe * (error code and message are in status an phrase parameters) * @param tags empty * * @sa NUTAG_OUTBOUND(), NUTAG_KEEPALIVE(), NUTAG_KEEPALIVE_STREAM(), * nua_register(), #nua_r_register, nua_unregister(), #nua_r_unregister * * @END_NUA_EVENT *//** @internal Callback from outbound_t */static int nua_stack_outbound_status(nua_handle_t *nh, outbound_t *ob, int status, char const *phrase, tag_type_t tag, tag_value_t value, ...){ ta_list ta; ta_start(ta, tag, value); nua_stack_event(nh->nh_nua, nh, NULL, nua_i_outbound, status, phrase, ta_args(ta)); ta_end(ta); return 0;}/** @internal Callback from outbound_t */static int nua_stack_outbound_failed(nua_handle_t *nh, outbound_t *ob, int status, char const *phrase, tag_type_t tag, tag_value_t value, ...){ ta_list ta; ta_start(ta, tag, value); nua_stack_event(nh->nh_nua, nh, NULL, nua_i_outbound, status, phrase, ta_args(ta)); ta_end(ta); return 0;}/** @internal Callback for obtaining credentials for keepalive */static int nua_stack_outbound_credentials(nua_handle_t *nh, auth_client_t **auc){ return auc_copy_credentials(auc, nh->nh_auth);}#include <ctype.h>#include <sofia-sip/bnf.h>/** @internal Generate a @Contact header. */sip_contact_t *nua_handle_contact_by_via(nua_handle_t *nh, su_home_t *home, int in_dialog, sip_via_t const *v, char const *transport, char const *m_param, ...){ su_strlst_t *l; char const *s; char const *host, *port, *maddr, *comp; int one = 1; char _transport[16]; va_list va; sip_contact_t *m; url_t url; url_init(&url, url_sip); if (!v) return NULL; host = v->v_host; if (v->v_received) host = v->v_received; port = sip_via_port(v, &one); maddr = v->v_maddr; comp = v->v_comp; if (host == NULL) return NULL; if (sip_transport_has_tls(v->v_protocol) || sip_transport_has_tls(transport)) { url.url_type = url_sips; if (port && strcmp(port, SIPS_DEFAULT_SERV) == 0) port = NULL; if (port || host_is_ip_address(host)) transport = NULL; } else if (port && host_is_ip_address(host) && strcmp(port, SIP_DEFAULT_SERV) == 0) { port = NULL; } if (transport) { if (strncasecmp(transport, "SIP/2.0/", 8) == 0) transport += 8; /* Make transport parameter lowercase */ if (strlen(transport) < (sizeof _transport)) { char *s = strcpy(_transport, transport); short c; for (s = _transport; (c = *s) && c != ';'; s++) if (isupper(c)) *s = tolower(c); transport = _transport; } } s = NH_PGET(nh, m_username); if (s) url.url_user = s; url.url_host = host; url.url_port = port; url.url_params = su_strdup(home, NH_PGET(nh, m_params)); if (transport) { url.url_params = url_strip_param_string((char*)url.url_params, "transport"); url_param_add(home, &url, su_sprintf(home, "transport=%s", transport)); } if (maddr) { url.url_params = url_strip_param_string((char*)url.url_params, "maddr"); url_param_add(home, &url, su_sprintf(home, "maddr=%s", maddr)); } if (comp) { url.url_params = url_strip_param_string((char*)url.url_params, "comp"); url_param_add(home, &url, su_sprintf(home, "comp=%s", comp)); } l = su_strlst_create(NULL); s = NH_PGET(nh, m_display); if (s) { int quote = s[span_token_lws(s)] != '\0'; su_strlst_append(l, quote ? "\"" : ""); su_strlst_append(l, s); su_strlst_append(l, quote ? "\" " : " "); } su_strlst_append(l, "<"); su_strlst_append(l, url_as_string(home, &url)); su_strlst_append(l, ">"); va_start(va, m_param); for (s = m_param; s; s = va_arg(va, char *)) { if (strlen(s) == 0) continue; su_strlst_append(l, s[0] == ';' ? "" : ";"); su_strlst_append(l, s); } va_end(va); if (!in_dialog) { s = NH_PGET(nh, m_features); if (s) s[0] == ';' ? "" : su_strlst_append(l, ";"), su_strlst_append(l, s); if (NH_PGET(nh, callee_caps)) { sip_allow_t const *allow = NH_PGET(nh, allow); if (allow) { su_strlst_append(l, ";methods=\""); if (allow->k_items) { size_t i; for (i = 0; allow->k_items[i]; i++) { su_strlst_append(l, allow->k_items[i]); if (allow->k_items[i + 1]) su_strlst_append(l, ","); } } su_strlst_append(l, "\""); } if (nh->nh_soa) { char **media = soa_media_features(nh->nh_soa, 0, home); while (*media) { if (su_strlst_len(l)) su_strlst_append(l, ";"); su_strlst_append(l, *media++); } } } } m = sip_contact_make(home, su_strlst_join(l, su_strlst_home(l), "")); su_strlst_destroy(l); return m;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -