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

📄 nua_register.c

📁 this is simple sip stack.
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (pair)      /* Don't use protocol if we have both udp and tcp */      protocol = NULL /*, v2[0].v_next = &v2[1], v2[1] = *pair */;    else      protocol = via->v_protocol /*, v2[0].v_next = NULL */;    contact = sip_contact_create_from_via_with_transport(home, v, NULL, protocol);    /* v = sip_via_dup(home, v2); */    if (!contact) {      su_free(home, nr);      break;    }    nr->nr_ready = 1, nr->nr_default = 1, nr->nr_public = public;    nr->nr_secure = contact->m_url->url_type == url_sips;    nr->nr_contact = contact;    /* nr->nr_via = v; */    SU_DEBUG_9(("nua_register: Adding contact URL '%s' to list.\n", contact->m_url->url_host));    ++nr_items;    nr->nr_next = *next, nr->nr_prev = next; *next = nr, next = &nr->nr_next;    nr->nr_list = list;  }  su_home_deinit(autohome);  return 0;}staticvoid nua_stack_tport_update(nua_t *nua, nta_agent_t *nta){#if 0  nua_registration_t *default_oc;  nua_registration_t const *defaults = nua->nua_registrations;  sip_via_t *via = nta_agent_via(nta);  default_oc = outbound_by_aor(defaults, NULL, 1);  if (default_oc) {    assert(default_oc->nr_via);    outbound_contacts_from_via(default_oc,				       via,				       via->v_next);    /* refresh_register(nua_handle_t *nh, nua_dialog_usage_t *du, sip_time_t now); */  }#endif  return;}nua_registration_t *nua_registration_by_aor(nua_registration_t const *list,					    sip_from_t const *aor,					    url_t const *remote_uri,					    int only_default){  sip_from_t *alt_aor = NULL, _alt_aor[1];  int sips_aor = aor && aor->a_url->url_type == url_sips;  int sips_uri = remote_uri && remote_uri->url_type == url_sips;  nua_registration_t const *nr, *public = NULL, *any = NULL;  nua_registration_t const *namewise = NULL, *sipswise = NULL;  if (only_default || aor == NULL) {    /* Ignore AoR, select only by remote_uri */    for (nr = list; nr; nr = nr->nr_next) {      if (!nr->nr_ready)	continue;      if (only_default && !nr->nr_default)	continue;      if (sips_uri ? nr->nr_secure : !nr->nr_secure) 	return (nua_registration_t *)nr;      if (!public && nr->nr_public)	public = nr;      if (!any)	any = nr;    }    if (public)      return (nua_registration_t *)public;    if (any)      return (nua_registration_t *)any;    return NULL;  }  if (!sips_aor && aor)    alt_aor = memcpy(_alt_aor, aor, sizeof _alt_aor);  for (nr = list; nr; nr = nr->nr_next) {    if (!nr->nr_ready)      continue;    if (nr->nr_aor) {      if (aor && url_cmp(nr->nr_aor->a_url, aor->a_url) == 0)	return (nua_registration_t *)nr;      if (!namewise && alt_aor && url_cmp(nr->nr_aor->a_url, aor->a_url) == 0)	namewise = nr;    }    if (!sipswise && (sips_aor || sips_uri) ? nr->nr_secure : !nr->nr_secure)       sipswise = nr;    if (!public && nr->nr_public)      public = nr;    if (!any)      any = nr;  }  if (namewise)    return (nua_registration_t *)namewise;  if (sipswise)    return (nua_registration_t *)sipswise;  /* XXX -      should we do some policing whether sips_aor or sips_uri can be used     with sip contact?  */  if (public)    return (nua_registration_t *)public;  if (any)    return (nua_registration_t *)any;  return NULL;}nua_registration_t *nua_registration_for_msg(nua_registration_t const *list, sip_t const *sip){  sip_from_t const *aor;  url_t *uri;  if (sip == NULL)    return NULL;  if (sip->sip_request) {    aor = sip->sip_from;    uri = sip->sip_request->rq_url;  }  else {    /* This is much hairier! */    aor = sip->sip_to;    if (sip->sip_record_route)      uri = sip->sip_record_route->r_url;    else if (sip->sip_contact)      uri = sip->sip_contact->m_url;    else      uri = sip->sip_from->a_url;    assert(uri != ((sip_contact_t *)NULL)->m_url);  }  return nua_registration_by_aor(list, aor, uri, 0);}/** Return Contact usable in dialogs */sip_contact_t const *nua_registration_contact(nua_registration_t const *nr){  if (nr->nr_by_stack && nr->nr_ob) {    sip_contact_t const *m = outbound_dialog_contact(nr->nr_ob);    if (m)      return m;  }  return nr->nr_contact;}/** Return initial route. */sip_route_t const *nua_registration_route(nua_registration_t const *nr){  return nr ? nr->nr_route : NULL;}sip_contact_t const *nua_stack_get_contact(nua_registration_t const *nr){  nr = nua_registration_by_aor(nr, NULL, NULL, 1);  return nr ? nr->nr_contact : NULL;}/** Add a Contact (and Route) header to request (or response) */int nua_registration_add_contact(nua_handle_t *nh,				 msg_t *msg,				 sip_t *sip,				 int add_contact,				 int add_service_route){  nua_registration_t *nr = NULL;  if (!add_contact && !add_service_route)    return 0;  if (nh == NULL || msg == NULL)    return -1;  if (sip == NULL)    sip = sip_object(msg);  if (nr == NULL)    nr = nua_registration_for_msg(nh->nh_nua->nua_registrations, sip);  if (nr == NULL)    return -1;  if (add_contact) {    sip_contact_t const *m = nua_registration_contact(nr);    if (!m || msg_header_add_dup(msg, (msg_pub_t *)sip, (void const *)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(su_home_t *home,				 nua_registration_t *nr,				 sip_contact_t const *application_contact,				 int terminating){  sip_contact_t *m = NULL, *previous;  url_t *uri;  if (!home || !nr)    return -1;  uri = nr->nr_aor ? nr->nr_aor->a_url : NULL;      previous = nr->nr_contact;  if (application_contact) {    m = sip_contact_dup(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)      m = sip_contact_dup(home, nr0->nr_contact);  }  if (!m)    return -1;  nr->nr_contact = m;  nr->nr_by_stack = !application_contact;  msg_header_free(home, (void *)previous);  return 0;}/** Mark registration as ready */void nua_registration_set_ready(nua_registration_t *nr, int ready){  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 */}/**@internal * Fix contacts for un-REGISTER. * * Remove (possible non-zero) "expires" parameters from contacts and extra * contacts, add Expire: 0. */staticvoid unregister_expires_contacts(msg_t *msg, sip_t *sip){  sip_contact_t *m;  int unregister_all;  if (msg == NULL || sip == NULL)    return;  /* Remove payload */  while (sip->sip_payload)    sip_header_remove(msg, sip, (sip_header_t *)sip->sip_payload);  while (sip->sip_content_type)    sip_header_remove(msg, sip, (sip_header_t *)sip->sip_content_type);  for (m = sip->sip_contact; m; m = m->m_next) {    if (m->m_url->url_type == url_any)      break;    msg_header_remove_param(m->m_common, "expires");#if 0    msg_header_add_param(msg_home(msg), m->m_common, "expires=0");#endif  }  unregister_all = m && (m != sip->sip_contact || m->m_next);  sip_add_tl(msg, sip,             /* Remove existing contacts */             TAG_IF(unregister_all, SIPTAG_CONTACT(NONE)),             /* Add '*' contact: 0 */             TAG_IF(unregister_all, SIPTAG_CONTACT_STR("*")),             SIPTAG_EXPIRES_STR("0"),             TAG_END());}/** Outbound requests us to refres registration */static int nua_stack_outbound_refresh(nua_handle_t *nh,				      outbound_t *ob){  nua_dialog_usage_t *du = nua_dialog_usage_get(nh->nh_ds, nua_register_usage, NULL);  if (du)    nua_dialog_usage_refresh(nh, du, 1);  return 0;}/** @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_tags(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_tags(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);}/** @internal Return a string describing our features. */static char *nua_handle_features(nua_handle_t *nh){  char *retval = NULL;  su_strlst_t *l = su_strlst_create(NULL);  su_home_t *home = su_strlst_home(l);  if (!l)    return NULL;  if (NH_PGET(nh, callee_caps)) {    sip_allow_t const *allow = NH_PGET(nh, allow);    if (allow) {      /* Skip ";" if this is first one */      su_strlst_append(l, ";methods=\"" + (su_strlst_len(l) == 0));      if (allow->k_items) {        int 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++);      }    }  }  if (su_strlst_len(l))    retval = su_strlst_join(l, nh->nh_home, "");  su_strlst_destroy(l);  return retval;}static int nua_stack_outbound_features(nua_handle_t *nh, outbound_t *ob){  char *features;  int retval;  if (!nh)    return -1;  if (!ob)    return 0;  features = nua_handle_features(nh);  retval = outbound_set_features(ob, features);  su_free(nh->nh_home, features);  return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -