⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nua_register.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -