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

📄 soa.c

📁 this is simple sip stack.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE soa.c * @brief Sofia SDP Offer/Answer Engine interface * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Wed Aug  3 20:27:15 EEST 2005 */#include "config.h"#include <stddef.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <assert.h>#include <sofia-sip/su_tag_class.h>#include <sofia-sip/su_wait.h>#include "sofia-sip/soa.h"#include "sofia-sip/sdp.h"#include "sofia-sip/soa_session.h"#include "sofia-sip/soa_add.h"#include <sofia-sip/hostdomain.h>#include <sofia-sip/su_tagarg.h>#include <sofia-sip/su_localinfo.h>#include <sofia-sip/su_uniqueid.h>#include <sofia-sip/string0.h>#include <sofia-sip/su_errno.h>#define NONE ((void *)-1)#define XXX assert(!"implemented")typedef unsigned longlong ull;#if HAVE_FUNC#elif HAVE_FUNCTION#define __func__ __FUNCTION__#elsestatic char const __func__[] = "soa";#endif/* ======================================================================== *//* Internal prototypes */void soa_set_activity(soa_session_t *ss,		      sdp_media_t const *,		      int remote);static inline int soa_media_is_ready(soa_session_t const *ss);enum soa_sdp_kind {   soa_capability_sdp_kind,  soa_user_sdp_kind,  soa_remote_sdp_kind};static int soa_set_sdp(soa_session_t *ss, 		       enum soa_sdp_kind what,		       sdp_session_t const *sdp0,		       char const *sdp_str, int str_len);/* ======================================================================== */#define SOA_VALID_ACTIONS(a)					\  ((a)->sizeof_soa_session_actions >= sizeof (*actions) &&	\   (a)->sizeof_soa_session >= sizeof(soa_session_t) &&		\   (a)->soa_name != NULL &&					\   (a)->soa_init != NULL &&					\   (a)->soa_deinit != NULL &&					\   (a)->soa_set_params != NULL &&				\   (a)->soa_get_params != NULL &&				\   (a)->soa_get_paramlist != NULL &&				\   (a)->soa_media_features != NULL &&				\   (a)->soa_sip_require != NULL &&				\   (a)->soa_sip_supported != NULL &&				\   (a)->soa_remote_sip_features != NULL &&			\   (a)->soa_set_capability_sdp != NULL &&			\   (a)->soa_set_remote_sdp != NULL &&				\   (a)->soa_set_user_sdp != NULL &&				\   (a)->soa_generate_offer != NULL &&				\   (a)->soa_generate_answer != NULL &&				\   (a)->soa_process_answer != NULL &&				\   (a)->soa_process_reject != NULL &&				\   (a)->soa_activate_session != NULL &&				\   (a)->soa_deactivate_session != NULL &&			\   (a)->soa_terminate_session != NULL)/* ======================================================================== *//**@var SOA_DEBUG * * Environment variable determining the default debug log level. * * The SOA_DEBUG environment variable is used to determine the default * debug logging level. The normal level is 3. * * @sa <su_debug.h>, su_log_global, SOFIA_DEBUG */extern char const SOA_DEBUG[];#ifndef SU_DEBUG#define SU_DEBUG 3#endif/**Debug log for @b soa module. * * The soa_log is the log object used by @b soa module. The level of * #soa_log is set using #SOA_DEBUG environment variable. */su_log_t soa_log[] = { SU_LOG_INIT("soa", "SOA_DEBUG", SU_DEBUG) };/* Add " around string */#define NICE(s) s ? "\"" : "", s ? s : "(nil)", s ? "\"" : ""/* ======================================================================== *//* API Functions */struct soa_namenode{  struct soa_namenode const *next;  char const *basename;  struct soa_session_actions const *actions;};#define SOA_NAMELISTLEN (16)static struct soa_namenode const soa_default_node =  {    NULL, "default", &soa_default_actions  };static struct soa_namenode const *soa_namelist = &soa_default_node;/** Add a named soa backend */int soa_add(char const *name,	    struct soa_session_actions const *actions){  struct soa_namenode const *n;  struct soa_namenode *e;  SU_DEBUG_9(("soa_add(%s%s%s, %p) called\n", NICE(name), actions));  if (name == NULL || actions == NULL)    return su_seterrno(EFAULT);  if (!SOA_VALID_ACTIONS(actions))    return su_seterrno(EINVAL);  for (n = soa_namelist; n; n = n->next) {    if (strcasecmp(name, n->basename) == 0)      return 0;  }  e = malloc(sizeof *e); if (!e) return -1;  e->next = soa_namelist;  e->basename = name;  e->actions = actions;  soa_namelist = e;  return 0;}/** Search for a named backend */struct soa_session_actions const *soa_find(char const *name){  SU_DEBUG_9(("soa_find(%s%s%s) called\n", NICE(name)));  if (name) {    struct soa_namenode const *n;    size_t baselen = strcspn(name, ":/");    for (n = soa_namelist; n; n = n->next) {      if (strncasecmp(name, n->basename, baselen) == 0)	break;    }    if (n == NULL)      return (void)su_seterrno(ENOENT), NULL;    return n->actions;  }  return NULL;}/* ======================================================================== */soa_session_t *soa_create(char const *name,			  su_root_t *root,			  soa_magic_t *magic){  struct soa_session_actions const *actions = &soa_default_actions;  soa_session_t *ss;  size_t namelen;  SU_DEBUG_9(("soa_create(\"%s\", %p, %p) called\n",	      name ? name : "default", root, magic));  if (name && name[0]) {    struct soa_namenode const *n;    size_t baselen = strcspn(name, ":/");    for (n = soa_namelist; n; n = n->next) {      if (strncasecmp(name, n->basename, baselen) == 0)	break;    }    if (n == NULL)      return (void)su_seterrno(ENOENT), NULL;    actions = n->actions; assert(actions);  }  else    name = "default";  assert(SOA_VALID_ACTIONS(actions));  if (root == NULL)    return (void)su_seterrno(EFAULT), NULL;  namelen = strlen(name) + 1;    ss = su_home_new(actions->sizeof_soa_session + namelen);  if (ss) {    ss->ss_root = root;    ss->ss_magic = magic;    ss->ss_actions = actions;    ss->ss_name = strcpy((char *)ss + actions->sizeof_soa_session, name);    if (ss->ss_actions->soa_init(name, ss, NULL) < 0)      ss->ss_actions->soa_deinit(ss), ss = NULL;  }  return ss;}soa_session_t *soa_clone(soa_session_t *parent_ss,			 su_root_t *root,			 soa_magic_t *magic){  soa_session_t *ss;  size_t namelen;  SU_DEBUG_9(("soa_clone(%s::%p, %p, %p) called\n",	      parent_ss ? parent_ss->ss_actions->soa_name : "",	      parent_ss, root, magic));  if (parent_ss == NULL || root == NULL)    return (void)su_seterrno(EFAULT), NULL;  namelen = strlen(parent_ss->ss_name) + 1;  ss = su_home_new(parent_ss->ss_actions->sizeof_soa_session + namelen);  if (ss) {    ss->ss_root = root;    ss->ss_magic = magic;    ss->ss_actions = parent_ss->ss_actions;    ss->ss_name = strcpy((char *)ss + ss->ss_actions->sizeof_soa_session,			 parent_ss->ss_name);    if (ss->ss_actions->soa_init(NULL, ss, parent_ss) < 0)      ss->ss_actions->soa_deinit(ss), ss = NULL;  }  return ss;}/** Increase reference count */soa_session_t *soa_session_ref(soa_session_t *ss){  SU_DEBUG_9(("soa_session_ref(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  return su_home_ref(ss->ss_home);}/** Decrease reference count */void soa_session_unref(soa_session_t *ss){  SU_DEBUG_9(("soa_session_unref(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  su_home_unref(ss->ss_home);}/* Initialize session */int soa_base_init(char const *name,		     soa_session_t *ss,		     soa_session_t *parent){  if (parent) {#define DUP(d, dup, s) if ((s) && !((d) = dup(ss->ss_home, (s)))) return -1    su_home_t *home = ss->ss_home;    if (soa_description_dup(home, ss->ss_caps, parent->ss_caps) < 0)      return -1;    if (soa_description_dup(home, ss->ss_user, parent->ss_user) < 0)      return -1;    if (soa_description_dup(home, ss->ss_local, parent->ss_local) < 0)      return -1;    if (soa_description_dup(home, ss->ss_remote, parent->ss_remote) < 0)      return -1;    DUP(ss->ss_address, su_strdup, parent->ss_address);    ss->ss_af = parent->ss_af;    DUP(ss->ss_hold, su_strdup, parent->ss_hold);    DUP(ss->ss_cname, su_strdup, parent->ss_cname);    ss->ss_srtp_enable = parent->ss_srtp_enable;    ss->ss_srtp_confidentiality = parent->ss_srtp_confidentiality;    ss->ss_srtp_integrity = parent->ss_srtp_integrity;  }  return 0;}/** Destroy a session. */void soa_destroy(soa_session_t *ss){  SU_DEBUG_9(("soa_destroy(%s::%p) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  if (ss) {    ss->ss_active = 0;    ss->ss_terminated++;    ss->ss_actions->soa_deinit(ss);    su_home_unref(ss->ss_home);  }}void soa_base_deinit(soa_session_t *ss){  (void)ss;}/** Set tagged parameters */int soa_set_params(soa_session_t *ss, tag_type_t tag, tag_value_t value, ...){  ta_list ta;  int n;  SU_DEBUG_9(("soa_set_params(%s::%p, ...) called\n",	      ss ? ss->ss_actions->soa_name : "", ss));  if (ss == NULL)    return su_seterrno(EFAULT), -1;  ta_start(ta, tag, value);  n = ss->ss_actions->soa_set_params(ss, ta_args(ta));  ta_end(ta);  return n;}int soa_base_set_params(soa_session_t *ss, tagi_t const *tags){  int n, change_session = 0;  sdp_session_t const *caps_sdp, *user_sdp;  char const *caps_sdp_str, *user_sdp_str;  int af;  char const *media_address, *hold;  unsigned rtp_select, rtp_sort;  int rtp_mismatch;  int srtp_enable, srtp_confidentiality, srtp_integrity;  af = ss->ss_af;  hold = ss->ss_hold;  media_address = ss->ss_address;  rtp_select = ss->ss_rtp_select;  rtp_sort = ss->ss_rtp_sort;  rtp_mismatch = ss->ss_rtp_mismatch;  srtp_enable = ss->ss_srtp_enable;  srtp_confidentiality = ss->ss_srtp_confidentiality;  srtp_integrity = ss->ss_srtp_integrity;  caps_sdp = user_sdp = NONE;  caps_sdp_str = user_sdp_str = NONE;  n = tl_gets(tags,	      SOATAG_CAPS_SDP_REF(caps_sdp),	      SOATAG_CAPS_SDP_STR_REF(caps_sdp_str),	      SOATAG_USER_SDP_REF(user_sdp),	      SOATAG_USER_SDP_STR_REF(user_sdp_str),	      SOATAG_AF_REF(af),	      SOATAG_ADDRESS_REF(media_address),	      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 = ss->ss_rtp_select;

⌨️ 快捷键说明

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