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

📄 soa.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 5 页
字号:
	      SOATAG_HOLD_REF(hold),	      SOATAG_RTP_SELECT_REF(rtp_select),	      SOATAG_RTP_SORT_REF(rtp_sort),	      SOATAG_RTP_MISMATCH_REF(rtp_mismatch),	      SOATAG_SRTP_ENABLE_REF(srtp_enable),	      SOATAG_SRTP_CONFIDENTIALITY_REF(srtp_confidentiality),	      SOATAG_SRTP_INTEGRITY_REF(srtp_integrity),	      TAG_END());  if (n <= 0)    return n;  if (caps_sdp != NONE || caps_sdp_str != NONE) {    if (caps_sdp == NONE) caps_sdp = NULL;    if (caps_sdp_str == NONE) caps_sdp_str = NULL;    if (caps_sdp || caps_sdp_str) {      if (soa_set_capability_sdp(ss, caps_sdp, caps_sdp_str, -1) < 0) {	return -1;      }    }    else {      soa_description_free(ss, ss->ss_caps);    }  }  if (user_sdp != NONE || user_sdp_str != NONE) {    if (user_sdp == NONE) user_sdp = NULL;    if (user_sdp_str == NONE) user_sdp_str = NULL;    if (user_sdp || user_sdp_str) {      if (soa_set_user_sdp(ss, user_sdp, user_sdp_str, -1) < 0) {	return -1;      }      if (ss->ss_caps->ssd_str == NULL)	soa_set_capability_sdp(ss, user_sdp, user_sdp_str, -1);    }    else {      soa_description_free(ss, ss->ss_user);    }  }  if (af < SOA_AF_ANY || af > SOA_AF_IP6_IP4)     af = ss->ss_af;  if (rtp_select < SOA_RTP_SELECT_SINGLE || rtp_select > SOA_RTP_SELECT_ALL)    rtp_select = (int)ss->ss_rtp_select;  if (rtp_sort < SOA_RTP_SORT_DEFAULT || rtp_sort > SOA_RTP_SORT_REMOTE)    rtp_sort = (int)ss->ss_rtp_sort;  rtp_mismatch = rtp_mismatch != 0;  srtp_enable = srtp_enable != 0;  srtp_confidentiality = srtp_confidentiality != 0;  srtp_integrity = srtp_integrity != 0;  change_session     =  af != (int)ss->ss_af    || rtp_select != (int)ss->ss_rtp_select    || rtp_sort != (int)ss->ss_rtp_sort    || rtp_mismatch != (int)ss->ss_rtp_mismatch    || srtp_enable != (int)ss->ss_srtp_enable    || srtp_confidentiality != (int)ss->ss_srtp_confidentiality    || srtp_integrity != (int)ss->ss_srtp_integrity    ;  ss->ss_af = af;  ss->ss_rtp_select = rtp_select;  ss->ss_rtp_sort = rtp_sort;  ss->ss_rtp_mismatch = rtp_mismatch;  ss->ss_srtp_enable = srtp_enable;  ss->ss_srtp_confidentiality = srtp_confidentiality;  ss->ss_srtp_integrity = srtp_integrity;  if (str0casecmp(media_address, ss->ss_address)) {    su_free(ss->ss_home, (void *)ss->ss_address);    ss->ss_address = su_strdup(ss->ss_home, media_address);    change_session = 1;  }  if (hold == (char const *)1)    hold = "*";  if (str0casecmp(hold, ss->ss_hold)) {    su_free(ss->ss_home, (void *)ss->ss_hold);    ss->ss_hold = su_strdup(ss->ss_home, hold);    change_session = 1;  }  if (change_session)    ss->ss_user_version++;  return n;}/** Get tagged parameters. * * @param ss soa session object * @param tag, value, ... tagged parameter list * * @return Number of parameters get, or -1 upon an error. * * @TAGS * SOATAG_CAPS_SDP(), * SOATAG_CAPS_SDP_STR(), * SOATAG_USER_SDP(), * SOATAG_USER_SDP_STR(), * SOATAG_LOCAL_SDP(), * SOATAG_LOCAL_SDP_STR(), * SOATAG_REMOTE_SDP(), * SOATAG_REMOTE_SDP_STR(), * SOATAG_AF(), * SOATAG_ADDRESS(), * SOATAG_AUDIO_AUX() (currently for "default" only), * SOATAG_HOLD(), * SOATAG_RTP_SELECT(), * SOATAG_RTP_SORT(), * SOATAG_RTP_MISMATCH(), * SOATAG_SRTP_ENABLE(), * SOATAG_SRTP_CONFIDENTIALITY(), and * SOATAG_SRTP_INTEGRITY(). */int soa_get_params(soa_session_t const *ss,		   tag_type_t tag, tag_value_t value, ...){  ta_list ta;  int n;  SU_DEBUG_9(("soa_get_params(%s::%p, ...) called\n",	      ss ? ss->ss_actions->soa_name : "", (void *)ss));  if (ss == NULL)    return su_seterrno(EFAULT), -1;  ta_start(ta, tag, value);  n = ss->ss_actions->soa_get_params(ss, ta_args(ta));  ta_end(ta);  return n;}/**Base method for getting tagged parameters. * * @param ss soa session object * @param tags   tag item list * * @return Number of parameters get, or -1 upon an error. * * @TAGS * SOATAG_CAPS_SDP(), * SOATAG_CAPS_SDP_STR(), * SOATAG_USER_SDP(), * SOATAG_USER_SDP_STR(), * SOATAG_LOCAL_SDP(), * SOATAG_LOCAL_SDP_STR(), * SOATAG_REMOTE_SDP(), * SOATAG_REMOTE_SDP_STR(), * SOATAG_AF(), * SOATAG_ADDRESS(), * SOATAG_HOLD(), * SOATAG_RTP_SELECT(), * SOATAG_RTP_SORT(), * SOATAG_RTP_MISMATCH(), * SOATAG_SRTP_ENABLE(), * SOATAG_SRTP_CONFIDENTIALITY(), and * SOATAG_SRTP_INTEGRITY(). */int soa_base_get_params(soa_session_t const *ss, tagi_t *tags){  int n;  n = tl_tgets(tags,	       SOATAG_CAPS_SDP(ss->ss_caps->ssd_sdp),	       SOATAG_CAPS_SDP_STR(ss->ss_caps->ssd_str),	       SOATAG_USER_SDP(ss->ss_user->ssd_sdp),	       SOATAG_USER_SDP_STR(ss->ss_user->ssd_str),	       SOATAG_LOCAL_SDP(ss->ss_local->ssd_sdp),	       SOATAG_LOCAL_SDP_STR(ss->ss_local->ssd_str),	       SOATAG_REMOTE_SDP(ss->ss_remote->ssd_sdp),	       SOATAG_REMOTE_SDP_STR(ss->ss_remote->ssd_unparsed),	       SOATAG_AF(ss->ss_af),	       SOATAG_ADDRESS(ss->ss_address),	       SOATAG_HOLD(ss->ss_hold),	       SOATAG_RTP_SELECT((int)ss->ss_rtp_select),	       SOATAG_RTP_SORT((int)ss->ss_rtp_sort),	       SOATAG_RTP_MISMATCH(ss->ss_rtp_mismatch),	       SOATAG_SRTP_ENABLE(ss->ss_srtp_enable),	       SOATAG_SRTP_CONFIDENTIALITY(ss->ss_srtp_confidentiality),	       SOATAG_SRTP_INTEGRITY(ss->ss_srtp_integrity),	       TAG_END());  return n;}/** Return a list of parameters. */tagi_t *soa_get_paramlist(soa_session_t const *ss,			  tag_type_t tag, tag_value_t value, ...){  ta_list ta;  tagi_t *params = NULL;  SU_DEBUG_9(("soa_get_paramlist(%s::%p, ...) called\n",	      ss ? ss->ss_actions->soa_name : "", (void *)ss));  if (ss) {    ta_start(ta, tag, value);    params = ss->ss_actions->soa_get_paramlist(ss, ta_tags(ta));    ta_end(ta);  }  return params;}/** Base bethod for getting list of parameters. */tagi_t *soa_base_get_paramlist(soa_session_t const *ss, 			       tag_type_t tag, tag_value_t value, 			       ...){  ta_list ta;  tagi_t *params;  if (ss == NULL)    return NULL;    ta_start(ta, tag, value);  params = tl_llist(		   TAG_IF(ss->ss_caps->ssd_sdp,			  SOATAG_CAPS_SDP(ss->ss_caps->ssd_sdp)),		   TAG_IF(ss->ss_caps->ssd_str,			  SOATAG_CAPS_SDP_STR(ss->ss_caps->ssd_str)),		   TAG_IF(ss->ss_user->ssd_sdp,			  SOATAG_USER_SDP(ss->ss_user->ssd_sdp)),		   TAG_IF(ss->ss_user->ssd_str,			  SOATAG_USER_SDP_STR(ss->ss_user->ssd_str)),		   TAG_IF(ss->ss_local->ssd_sdp,			  SOATAG_LOCAL_SDP(ss->ss_local->ssd_sdp)),		   TAG_IF(ss->ss_user->ssd_str,			  SOATAG_LOCAL_SDP_STR(ss->ss_local->ssd_str)),		   TAG_IF(ss->ss_remote->ssd_sdp,			  SOATAG_REMOTE_SDP(ss->ss_remote->ssd_sdp)),		   TAG_IF(ss->ss_remote->ssd_str,			  SOATAG_REMOTE_SDP_STR(ss->ss_remote->ssd_unparsed)),		   SOATAG_AF(ss->ss_af),		   TAG_IF(ss->ss_address, 			  SOATAG_ADDRESS(ss->ss_address)),		   SOATAG_SRTP_ENABLE(ss->ss_srtp_enable),		   SOATAG_SRTP_CONFIDENTIALITY(ss->ss_srtp_confidentiality),		   SOATAG_SRTP_INTEGRITY(ss->ss_srtp_integrity),		   ta_tags(ta));  ta_end(ta);  return params;}#include <sofia-sip/sip_status.h>/** Convert @soa error to a SIP response code and phrase. */ int soa_error_as_sip_response(soa_session_t *ss,			      char const **return_phrase){  SU_DEBUG_9(("soa_error_as_sip_response(%s::%p, ...) called\n",	      ss ? ss->ss_actions->soa_name : "", (void *)ss));  if (ss == NULL || ss->ss_status < 400 || ss->ss_status >= 700) {    if (return_phrase)      *return_phrase = sip_500_Internal_server_error;    return 500;  }  if (return_phrase)    *return_phrase = ss->ss_phrase;  return ss->ss_status;}/** Convert @soa error to a SIP @Reason header. */ char const *soa_error_as_sip_reason(soa_session_t *ss){  char const *phrase;  int status;  char *reason;  SU_DEBUG_9(("soa_error_as_sip_reason(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", (void *)ss));  if (ss == NULL)    return "SIP;cause=500;text=\"Internal Server Error\"";  status = soa_error_as_sip_response(ss, &phrase);  reason = su_sprintf(ss->ss_home, "SIP;cause=%u;text=\"%s\"", status, phrase);    if (ss->ss_reason)    su_free(ss->ss_home, reason);  return ss->ss_reason = reason;}/** Return SIP @Warning code and text. */int soa_get_warning(soa_session_t *ss, char const **return_text){  if (!ss)    return 0;  if (!ss->ss_wcode)    return 0;  if (return_text)    *return_text = ss->ss_warning;  return ss->ss_wcode;}/** Return SDP description of capabilities. * * @param ss  pointer to @soa session * @param return_sdp      return value for capability SDP structure  * @param return_sdp_str  return value for capability SDP string * @param return_len  return value for length of capability SDP string * * @retval 0 if there is no description to return * @retval 1 if description is returned * @retval -1 upon an error * * @sa @RFC3261 section 11, soa_set_capability_sdp(),  * SOATAG_CAPS_SDP(), SOATAG_CAPS_SDP_STR(),  * nua_options(), #nua_i_options */int soa_get_capability_sdp(soa_session_t const *ss,			   struct sdp_session_s const **return_sdp,			   char const **return_sdp_str,			   isize_t *return_len){  sdp_session_t const *sdp;  char const *sdp_str;  SU_DEBUG_9(("soa_get_capability_sdp(%s::%p, [%p], [%p], [%p]) called\n",	      ss ? ss->ss_actions->soa_name : "", (void *)ss,	      (void *)return_sdp, (void *)return_sdp_str, (void *)return_len));  if (ss == NULL)    return (void)su_seterrno(EFAULT), -1;  sdp = ss->ss_caps->ssd_sdp;  sdp_str = ss->ss_caps->ssd_str;  if (sdp == NULL)    return 0;  if (return_sdp)    *return_sdp = sdp;  if (return_sdp_str)    *return_sdp_str = sdp_str;  if (return_len)    *return_len = strlen(sdp_str);  return 1;}/** Set capability SDP.  * * Capability SDP is used instead of user SDP when generating OPTIONS * responses describing media capabilities.  * * @param ss  pointer to @soa session * @param sdp pointer to SDP session structure * @param str pointer to string containing SDP session description * @param len lenght of string @a str * * @retval 1 when SDP is stored and it differs from previously stored * @retval 0 when SDP is identical to previously stored one (and user version *           returned by soa_get_user_version() is not incremented) * @retval -1 upon an error * * @sa @RFC3261 section 11, soa_get_capability_sdp(), * SOATAG_CAPS_SDP(), SOATAG_CAPS_SDP_STR(),  * nua_options(), #nua_i_options */int soa_set_capability_sdp(soa_session_t *ss, 			   struct sdp_session_s const *sdp,			   char const *str, issize_t len){  SU_DEBUG_9(("soa_set_capability_sdp(%s::%p, %p, %p, "MOD_ZD") called\n",	      ss ? ss->ss_actions->soa_name : "", (void *)ss, (void *)sdp, (void *)str, (ssize_t)len));  return soa_set_sdp(ss, soa_capability_sdp_kind, sdp, str, len);}/** Set capabilities */int soa_base_set_capability_sdp(soa_session_t *ss,			    sdp_session_t *_sdp,			    char const *str0, isize_t len0){  sdp_session_t sdp[1];  sdp_origin_t o[1] = {{ sizeof(o) }};  sdp_connection_t *c, c0[1] = {{ sizeof(c0) }};  char c_address[64];  sdp_time_t t[1] = {{ sizeof(t) }};  sdp_media_t *m;  *sdp = *_sdp;  if (sdp->sdp_origin)    *o = *sdp->sdp_origin;  else    o->o_address = c0;  if (soa_init_sdp_origin(ss, o, c_address) < 0)    return -1;  sdp->sdp_origin = o;  if (!sdp->sdp_subject)    sdp->sdp_subject = "-";	/* s=- */  sdp->sdp_time = t;		/* t=0 0 */  /* Set port to zero - or should we check that port is already zero? */  for (m = sdp->sdp_media; m; m = m->m_next)    m->m_port = 0;  if (sdp->sdp_connection == NULL) {    c = sdp->sdp_origin->o_address;    for (m = sdp->sdp_media; m; m = m->m_next)      if (m->m_connections == NULL)	break;    if (m)      sdp->sdp_connection = c;  }  return soa_description_set(ss, ss->ss_caps, sdp, str0, len0);}/**Return user SDP description. * * <i>User SDP</i> is used as basis for SDP Offer/Answer negotiation. It can * be very minimal template, consisting just m= line containing media name, * transport protocol port number and list of supported codecs. * * The SDP used as an offer or answer (generated by soa_generate_answer() or * soa_generate_offer()) is known as <i>local SDP</i> and it is available * with soa_get_local_sdp() or SOATAG_LOCAL_SDP()/SOATAG_LOCAL_SDP_STR() * tags. * * @param ss  pointer to @soa session * @param return_sdp SDP  session structure return value * @param return_sdp_str  return value for pointer to string 

⌨️ 快捷键说明

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