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

📄 soa.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
		   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>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 : "", 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;}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 : "", 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 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. * * @retval 0 if there is no description to return * @retval 1 if description is returned * @retval -1 upon an error */int soa_get_capability_sdp(soa_session_t const *ss,			   sdp_session_t const **return_sdp,			   char const **return_sdp_str,			   int *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 : "", ss,	      return_sdp, return_sdp_str, 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;}int soa_set_capability_sdp(soa_session_t *ss, 			   sdp_session_t const *sdp,			   char const *str, int len){  SU_DEBUG_9(("soa_set_capability_sdp(%s::%p, %p, %p, %d) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, sdp, str, 	      str && len == -1 ? (int)strlen(str) : 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, int len0){  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;  if (sdp->sdp_origin)    *o = *sdp->sdp_origin;  else    o->o_address = c0;  sdp->sdp_origin = o;  if (soa_init_sdp_origin(ss, o, c_address) < 0)    return -1;  if (!sdp->sdp_subject)    sdp->sdp_subject = "-";  sdp->sdp_time = t;  /* 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;  c = sdp->sdp_origin->o_address;  if (sdp->sdp_connection == NULL) {    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 SDP description of the session. * * @retval 0 if there is no description to return * @retval 1 if description is returned * @retval -1 upon an error */int soa_get_user_sdp(soa_session_t const *ss,		     sdp_session_t const **return_sdp,		     char const **return_sdp_str,		     int *return_len){  sdp_session_t const *sdp;  char const *sdp_str;  SU_DEBUG_9(("soa_get_user_sdp(%s::%p, [%p], [%p], [%p]) called\n",	      ss ? ss->ss_actions->soa_name : "", ss,	      return_sdp, return_sdp_str, return_len));  if (ss == NULL)    return (void)su_seterrno(EFAULT), -1;  sdp = ss->ss_user->ssd_sdp;  sdp_str = ss->ss_user->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;}/**  * Returns the version number of user session * description. The version numbering starts from * zero and is incremented for each modification. */int soa_get_user_version(soa_session_t const *ss){  assert(ss != NULL);  return ss ? ss->ss_user_version : -1;} int soa_set_user_sdp(soa_session_t *ss, 		     sdp_session_t const *sdp,		     char const *str, int len){  SU_DEBUG_9(("soa_set_user_sdp(%s::%p, %p, %p, %d) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, sdp, str, 	      str && len == -1 ? (int)strlen(str) : len));  return soa_set_sdp(ss, soa_user_sdp_kind, sdp, str, len);}/** Set user SDP (base version). */int soa_base_set_user_sdp(soa_session_t *ss, 			   sdp_session_t *sdp, char const *str0, int len0){  ++ss->ss_user_version;  return soa_description_set(ss, ss->ss_user, sdp, str0, len0);}/** Return remote SDP description of the session. * * @retval 0 if there is no description to return * @retval 1 if description is returned * @retval -1 upon an error */int soa_get_remote_sdp(soa_session_t const *ss,		       sdp_session_t const **return_sdp,		       char const **return_sdp_str,		       int *return_len){  sdp_session_t const *sdp;  char const *sdp_str;  SU_DEBUG_9(("soa_get_remote_sdp(%s::%p, [%p], [%p], [%p]) called\n",	      ss ? ss->ss_actions->soa_name : "", ss,	      return_sdp, return_sdp_str, return_len));  if (ss == NULL)    return (void)su_seterrno(EFAULT), -1;  sdp = ss->ss_remote->ssd_sdp;  sdp_str = ss->ss_remote->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;}/**  * Returns the version number of remote session * description. The version numbering starts from * zero and is incremented for each modification. */int soa_get_remote_version(soa_session_t const *ss){  assert(ss != NULL);  return ss->ss_remote_version;} /** Set remote SDP (offer or answer) */int soa_set_remote_sdp(soa_session_t *ss, 		       sdp_session_t const *sdp,		       char const *str, int len){  SU_DEBUG_9(("soa_set_remote_sdp(%s::%p, %p, %p, %d) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, sdp, str, 	      str && len == -1 ? (int)strlen(str) : len));  return soa_set_sdp(ss, soa_remote_sdp_kind, sdp, str, len);}/** Set remote SDP (base version). */int soa_base_set_remote_sdp(soa_session_t *ss,			    int new_version,			    sdp_session_t *sdp, char const *str0, int len0){  /* This is cleared in soa_generate_answer() or soa_process_answer(). */  ss->ss_unprocessed_remote = 1;  if (!new_version)    return 0;      soa_set_activity(ss, sdp->sdp_media, 1);  ss->ss_remote_version++;    return soa_description_set(ss, ss->ss_remote, sdp, str0, len0);}int soa_clear_remote_sdp(soa_session_t *ss){  SU_DEBUG_9(("soa_clear_remote_sdp(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  if (!ss)    return (void)su_seterrno(EFAULT), -1;  ss->ss_unprocessed_remote = 0;  return 0;}/** Get local SDP. * * The local SDP is usually result of SDP negotiation. */int soa_get_local_sdp(soa_session_t const *ss,		      sdp_session_t const **return_sdp,		      char const **return_sdp_str,		      int *return_len){  sdp_session_t const *sdp;  char const *sdp_str;  SU_DEBUG_9(("soa_get_local_sdp(%s::%p, [%p], [%p], [%p]) called\n",	      ss ? ss->ss_actions->soa_name : "", ss,	      return_sdp, return_sdp_str, return_len));  if (ss == NULL)    return (void)su_seterrno(EFAULT), -1;  sdp = ss->ss_local->ssd_sdp;  sdp_str = ss->ss_local->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;}/** Initialize offer/answer state machine */int soa_init_offer_answer(soa_session_t *ss){  int complete;  SU_DEBUG_9(("soa_init_offer_answer(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  if (!ss)    return 0;  complete = ss->ss_complete;  ss->ss_complete = 0;  ss->ss_offer_sent = 0;  ss->ss_offer_recv = 0;  ss->ss_answer_sent = 0;  ss->ss_answer_recv = 0;  ss->ss_unprocessed_remote = 0;  return complete;}char **soa_media_features(soa_session_t *ss, int live, su_home_t *home){  SU_DEBUG_9(("soa_media_features(%s::%p, %u, %p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, live, home));  if (ss)    return ss->ss_actions->soa_media_features(ss, live, home);  else    return (void)su_seterrno(EFAULT), NULL;}char **soa_base_media_features(soa_session_t *ss, int live, su_home_t *home){  return su_zalloc(home, 8 * sizeof (char **));}char const * const * soa_sip_require(soa_session_t const *ss){  SU_DEBUG_9(("soa_sip_require(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  if (ss)    return ss->ss_actions->soa_sip_require(ss);  else    return (void)su_seterrno(EFAULT), NULL;}char const * const * soa_base_sip_require(soa_session_t const *ss){  static char const *null = NULL;  return &null;}char const * const * soa_sip_supported(soa_session_t const *ss){  SU_DEBUG_9(("soa_sip_supported(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  if (ss)    return ss->ss_actions->soa_sip_supported(ss);  else    return (void)su_seterrno(EFAULT), NULL;}char const * const * soa_base_sip_supported(soa_session_t const *ss){  static char const *null = NULL;  return &null;}int soa_remote_sip_features(soa_session_t *ss,			    char const * const * supported,			    char const * const * require){  SU_DEBUG_9(("soa_remote_sip_features(%s::%p, %p, %p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, supported, require));  if (ss)    return ss->ss_actions->soa_remote_sip_features(ss, supported, require);  else    return (void)su_seterrno(EFAULT), -1;}int soa_base_remote_sip_features(soa_session_t *ss,				    char const * const * supported,				    char const * const * require){  return 0;}/** Run Offer step. * * @param ss pointer to session object * @param always always send offer (even if offer/answer has been completed) * @param completed pointer to callback function which is invoked when *                  operation is completed * * @retval 1 when operation is successful * @retval 0 when operation is not needed * @retval -1 upon an error * * @ERRORS */int soa_generate_offer(soa_session_t *ss,		       int always,		       soa_callback_f *completed){  SU_DEBUG_9(("soa_generate_offer(%s::%p, %u, %p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, always, completed));  /** @ERROR EFAULT Bad address. */  if (ss == NULL)    return su_seterrno(EFAULT), -1;  /** @ERROR An operation is already in progress */  if (ss->ss_in_progress)    return su_seterrno(EALREADY), -1;  /** @ERROR EPROTO We have received offer, now we should send answer */  if (ss->ss_offer_recv && !ss->ss_answer_sent)    return su_seterrno(EPROTO), -1;  /** @ERROR EPROTO We have received SDP, but it has not been processed */  if (soa_has_received_sdp(ss))    return su_seterrno(EPROTO), -1;  /** @ERROR EPROTO We have sent an offer, but have received no answer */  if (ss->ss_offer_sent && !ss->ss_answer_recv)    return su_seterrno(EPROTO), -1;  /** @ERROR EPROTO We have received offer. */  if (ss->ss_unprocessed_remote)    return su_seterrno(EPROTO), -1;  /* We should avoid actual operation unless always is true */  (void)always;  /* We always regenerate offer */  return ss->ss_actions->soa_generate_offer(ss, completed);}int soa_base_generate_offer(soa_session_t *ss,			    soa_callback_f *completed){  sdp_session_t const *sdp = ss->ss_local->ssd_sdp;  (void)completed;  if (!sdp)    return -1;  soa_set_activity(ss, sdp->sdp_media, 0);  ss->ss_offer_sent = 1;  ss->ss_answer_recv = 0;  return 0;}/* Generate answer */int soa_generate_answer(soa_session_t *ss,			soa_callback_f *completed){  SU_DEBUG_9(("soa_generate_answer(%s::%p, %p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, completed));  /** @ERROR EFAULT Bad address as @a ss. */  if (ss == NULL)    return su_seterrno(EFAULT), -1;  /** @ERROR An operation is already in progress. */  if (ss->ss_in_progress)    return su_seterrno(EALREADY), -1;  /** @ERROR EPROTO We have sent an offer, but have received no answer. */  if (ss->ss_offer_sent && !ss->ss_answer_recv)    return su_seterrno(EPROTO), -1;  /** @ERROR EPROTO We have not received offer. */  if (!ss->ss_unprocessed_remote)    return su_seterrno(EPROTO), -1;  return ss->ss_actions->soa_generate_answer(ss, completed);}int soa_base_generate_answer(soa_session_t *ss,			     soa_callback_f *completed){  sdp_session_t const *l_sdp = ss->ss_local->ssd_sdp;  sdp_session_t const *r_sdp = ss->ss_remote->ssd_sdp;  sdp_session_t *rsession;  (void)completed;  if (!l_sdp || !r_sdp)    return -1;  rsession = sdp_session_dup(ss->ss_home, r_sdp);  if (!rsession)    return -1;  if (ss->ss_rsession)    su_free(ss->ss_home, ss->ss_rsession);  ss->ss_rsession = rsession;  soa_set_activity(ss, l_sdp->sdp_media, 0);  soa_set_activity(ss, r_sdp->sdp_media, 1);  ss->ss_offer_recv = 1;  ss->ss_answer_sent = 1;  ss->ss_complete = 1;  ss->ss_unprocessed_remote = 0;  return 0;}/** Complete offer-answer after receiving answer */int soa_process_answer(soa_session_t *ss,		       soa_callback_f *completed){  SU_DEBUG_9(("soa_process_answer(%s::%p, %p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss, completed));  /** @ERROR EFAULT Bad address as @a ss. */  if (ss == NULL)    return su_seterrno(EFAULT), -1;  /** @ERROR An operation is already in progress. */  if (ss->ss_in_progress)    return su_seterrno(EALREADY), -1;  /** @ERROR EPROTO We have not sent an offer       or already have received answer. */  if (!ss->ss_offer_sent || ss->ss_answer_recv)    return su_seterrno(EPROTO), -1;  /** @ERROR EPROTO We have not received answer. */  if (!ss->ss_unprocessed_remote)    return su_seterrno(EPROTO), -1;  return ss->ss_actions->soa_process_answer(ss, completed);}/**  * Processes answer from remote end. */int soa_base_process_answer(soa_session_t *ss,			    soa_callback_f *completed){  sdp_session_t const *l_sdp = ss->ss_local->ssd_sdp;  sdp_session_t const *r_sdp = ss->ss_remote->ssd_sdp;  sdp_session_t *rsession;  (void)completed;  if (!l_sdp || !r_sdp)    return -1;  rsession = sdp_session_dup(ss->ss_home, r_sdp);  if (!rsession)    return -1;  if (ss->ss_rsession)    su_free(ss->ss_home, ss->ss_rsession);  ss->ss_rsession = rsession;  soa_set_activity(ss, l_sdp->sdp_media, 0);

⌨️ 快捷键说明

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