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

📄 sip_basic.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   msg_param_t         af_duration;  // Duration parameter * } sip_retry_after_t; * @endcode *//**@ingroup sip_retry_after * @brief Structure for @b Retry-After header. */static msg_xtra_f sip_retry_after_dup_xtra;static msg_dup_f sip_retry_after_dup_one;static msg_update_f sip_retry_after_update;msg_hclass_t sip_retry_after_class[] = SIP_HEADER_CLASS(retry_after, "Retry-After", "", af_params, single,		 retry_after);int sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, int slen){  sip_retry_after_t *af = h->sh_retry_after;  if ((msg_delta_d((char const **)&s, &af->af_delta) < 0) ||      (*s == '(' && msg_comment_d(&s, &af->af_comment) == -1) ||      (*s == ';' && msg_params_d(home, &s, &af->af_params) == -1) ||      (*s != '\0')) {    if (af->af_params)      su_free(home, (void *)af->af_params), af->af_params = NULL;    return -1;  }  if (af->af_params)    msg_header_update_params(h->sh_common, 0);  return 0;}int sip_retry_after_e(char b[], int bsiz, sip_header_t const *h, int f){  sip_retry_after_t const *af = h->sh_retry_after;  int const compact = MSG_IS_COMPACT(f);  char *b0 = b, *end = b + bsiz;  b += snprintf(b, bsiz, "%lu", af->af_delta);  if (af->af_comment) {    if (!compact)       MSG_CHAR_E(b, end, ' ');    MSG_CHAR_E(b, end, '(');    MSG_STRING_E(b, end, af->af_comment);    MSG_CHAR_E(b, end, ')');    if (!compact && af->af_params && af->af_params[0])      MSG_CHAR_E(b, end, ' ');  }  if (af->af_params)    MSG_PARAMS_E(b, end, af->af_params, f);      MSG_TERM_E(b, end);      return b - b0;}int sip_retry_after_dup_xtra(sip_header_t const *h, int offset){  int rv = offset;  sip_retry_after_t const *af = h->sh_retry_after;  MSG_PARAMS_SIZE(rv, af->af_params);  rv += MSG_STRING_SIZE(af->af_comment);  return rv;}char *sip_retry_after_dup_one(sip_header_t *dst,			      sip_header_t const *src,			      char *b,			      int xtra){  sip_retry_after_t *af = dst->sh_retry_after;  sip_retry_after_t const *o = src->sh_retry_after;  char *end = b + xtra;  b = msg_params_dup(&af->af_params, o->af_params, b, xtra);  MSG_STRING_DUP(b, af->af_comment, o->af_comment);  af->af_delta = o->af_delta;  assert(b <= end);  return b;}static int sip_retry_after_update(msg_common_t *h,				  char const *name, int namelen,				  char const *value){  sip_retry_after_t *af = (sip_retry_after_t *)h;  if (name == NULL) {    af->af_duration = NULL;  }  else if (namelen == strlen("duration") &&	   !strncasecmp(name, "duration", namelen)) {    af->af_duration = value;  }  return 0;}/* ====================================================================== *//**  * Parse a Route/Record-Route header * * The function sip_route_d() parses a Route or a Record-Route header. * * @retval 0 when successful,  * @retval -1 upon an error. */int sip_any_route_d(su_home_t *home,		    sip_header_t *h,		    char *s,		    int slen){  sip_header_t **hh = &h->sh_succ, *h0 = h;  sip_route_t *r = h->sh_route;  assert(h);  /* Loop through comma-separated list of route headers.. */  for (;*s;) {    /* Ignore empty entries (comma-whitespace) */    if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; }    if (!h) {      if (!(h = sip_header_alloc(home, h0->sh_class, 0)))	break;      *hh = h; h->sh_prev = hh; hh = &h->sh_succ;      r = r->r_next = h->sh_route;    }    r = h->sh_route;    if (sip_name_addr_d(home, &s, &r->r_display, 			r->r_url, &r->r_params, NULL) < 0)      return -1;    if (*s != '\0' && *s != ',')      return -1;    h = NULL;  }  if (h)		/* Empty list is an error */    return -1;  return 0;}int sip_any_route_e(char b[], int bsiz, sip_header_t const *h, int flags){  sip_route_t const *r = h->sh_route;  return sip_name_addr_e(b, bsiz, flags, 			 r->r_display, 1, r->r_url, r->r_params, NULL);}int sip_any_route_dup_xtra(sip_header_t const *h, int offset){  int rv = offset;  sip_route_t const *r = h->sh_route;  MSG_PARAMS_SIZE(rv, r->r_params);  rv += MSG_STRING_SIZE(r->r_display);  rv += url_xtra(r->r_url);  return rv;}char *sip_any_route_dup_one(sip_header_t *dst, sip_header_t const *src,			    char *b,			    int xtra){  sip_route_t *r = dst->sh_route;  sip_route_t const *o = src->sh_route;  char *end = b + xtra;  b = msg_params_dup(&r->r_params, o->r_params, b, xtra);  MSG_STRING_DUP(b, r->r_display, o->r_display);  URL_DUP(b, end, r->r_url, o->r_url);      assert(b <= end);  return b;}#define sip_any_route_update NULL/** Create a route.  * * The function sip_any_route_create() creates a route or record-route entry * from two URLs; first one provides the URL, second maddr parameter and * port. * * @param home   memory home * @param rq_url route URL * @param maddr  optional route address and port *  */staticsip_route_t *sip_any_route_create(su_home_t *home,			       msg_hclass_t *hc,			       url_t const *rq_url,			       url_t const *maddr){  sip_header_t *h;  sip_route_t *rr;  url_t url[1];   int xtra, n, n_url, n_params, n_addr;   char *b, *param;  *url = *rq_url;  if (maddr) {    url->url_port = maddr->url_port;    url->url_params = NULL;  }  n_url = url_xtra(url);  n_params = maddr && maddr->url_params ? strlen(maddr->url_params) : 0;  if (maddr && (!maddr->url_params || 		!url_param(maddr->url_params, "maddr", NULL, 0)))    n_addr = (n_params != 0) + strlen("maddr=") + strlen(maddr->url_host);  else     n_addr = 0;  xtra = n_url + n_params + n_addr + (n_params || n_addr);  h = sip_header_alloc(home, hc, xtra);  if ((rr = h->sh_record_route)) {    b = sip_header_data(h);    n = url_dup(b, n_url, rr->r_url, url);    assert(n == n_url);    if (n_params || n_addr) {      param = b + n_url;      if (n_params) {	rr->r_url->url_params = strcpy(param, maddr->url_params);	param += n_params;      }      if (n_addr) {	if (n_params)	  *param++ = ';';	strcpy(param, "maddr="), param += strlen("maddr=");	strcpy(param, maddr->url_host), param += strlen(maddr->url_host);      }      assert(b + xtra == param + 1);    }  }  return rr;}/* ====================================================================== *//**@SIP_HEADER sip_route Route Header * * The Route headers is used to store the route set of a transaction.   * The Route header is defined in [S10.38] as follows: *  * @code *    Route        =  "Route" HCOLON route-param *(COMMA route-param) *    route-param  =  name-addr *( SEMI rr-param ) * @endcode * *//**@ingroup sip_route * @typedef typedef struct sip_route_s sip_route_t; * * The structure #sip_route_t contains representation of SIP @b Route header. * * The #sip_route_t is defined as follows: * @code * typedef struct sip_route_s { *   sip_common_t        r_common[1];   // Common fragment info *   sip_route_t        *r_next;        // Link to next Route *   char const         *r_display;     // Display name *   url_t               r_url[1];      // Route URL *   msg_param_t const  *r_params;      // List of route parameters * } sip_route_t; * @endcode */msg_hclass_t sip_route_class[] = SIP_HEADER_CLASS(route, "Route", "", r_params, append, any_route);int sip_route_d(su_home_t *home,		sip_header_t *h,		char *s,		int slen){  return sip_any_route_d(home, h, s, slen);}int sip_route_e(char b[], int bsiz, sip_header_t const *h, int flags){  assert(sip_is_route(h));  return sip_any_route_e(b, bsiz, h, flags);}/**@ingroup sip_route  * @brief Create a @b Route header object. * * The function sip_route_create() creates a route entry from two URLs; * first one provides the URL, second maddr parameter and port. * * @param home   memory home * @param url    route URL * @param maddr  optional route address and port * * @return * The function sip_route_create() returns a pointer to newly created * @b Route header object when successful, or NULL upon an error. */sip_route_t *sip_route_create(su_home_t *home, 			      url_t const *url, 			      url_t const *maddr){  return sip_any_route_create(home, sip_route_class, url, maddr);  }/* ====================================================================== *//**@SIP_HEADER sip_record_route Record-Route Header * * The Record-Route headers are used to establish a route for transactions * belonging to a session.  The Record-Route header is defined in [S10.34] * as follows:  *  * @code *    Record-Route  =  "Record-Route" HCOLON rec-route *(COMMA rec-route) *    rec-route     =  name-addr *( SEMI rr-param ) *    rr-param      =  generic-param * @endcode * *//**@ingroup sip_record_route * @typedef typedef struct sip_record_route_s sip_record_route_t; * * The structure #sip_record_route_t contains representation of SIP * @b Record-Route header. * * The #sip_record_route_t is defined as follows: * @code * typedef struct sip_record_route_s { *   sip_common_t        r_common[1];   // Common fragment info *   sip_route_t        *r_next;        // Link to next Record-Route *   char const         *r_display;     // Display name *   url_t               r_url[1];      // Route URL *   msg_param_t const  *r_params;      // List of route parameters * } sip_record_route_t; * @endcode */msg_hclass_t sip_record_route_class[] = SIP_HEADER_CLASS(record_route, "Record-Route", "",		 r_params, prepend, any_route);int sip_record_route_d(su_home_t *home,		       sip_header_t *h,		       char *s,		       int slen){  return sip_any_route_d(home, h, s, slen);}int sip_record_route_e(char b[], int bsiz, sip_header_t const *h, int flags){  assert(sip_is_record_route(h));  return sip_any_route_e(b, bsiz, h, flags);}/** @ingroup sip_record_route  * * Create a record-route.  * * The function sip_record_route_create() creates a record-route entry * from two URLs; first one provides the URL, second maddr parameter and * port. * * @param home   memory home * @param rq_url route URL * @param maddr  optional route address and port * * @return * The function sip_record_route_create() returns a pointer to newly * created Record-Route header object when successful or NULL upon an * error. */sip_record_route_t *sip_record_route_create(su_home_t *home,					    url_t const *rq_url,					    url_t const *maddr){  return sip_any_route_create(home, sip_record_route_class, rq_url, maddr);}/* ====================================================================== *//**@SIP_HEADER sip_to To Header * * The To header field specifies the "logical" recipient of the * request.  It is defined in [S10.43] as follows: *  * @code *    To        =  ( "To" / "t" ) HCOLON ( name-addr *                 / addr-spec ) *( SEMI to-param ) *    to-param  =  tag-param / generic-param * @endcode * *//**@ingroup sip_to * @typedef typedef struct sip_addr_s sip_to_t; * * The structure sip_to_t contains representation of @b To header. * * The sip_to_t is defined as follows: * @code * typedef struct { *   sip_common_t       a_common[1];    // Common fragment info *   sip_unknown_t     *a_next;         // Link to next (dummy) *   char const        *a_display;      // Display name *   url_t              a_url[1];       // URL *   msg_param_t const *a_params;       // List of to-params *   char const        *a_comment;      // Comment *   char const        *a_tag;          // Tag parameter  * } sip_to_t; * @endcode * */msg_hclass_t sip_to_class[] = SIP_HEADER_CLASS(to, "To", "t", a_params, single, addr);int sip_to_d(su_home_t *home,	     sip_header_t *h,	     char *s,	     int slen){  return sip_addr_d(home, h, s, slen);}int sip_to_e(char b[], int bsiz, sip_header_t const *h, int flags){  assert(sip_is_to(h));  return sip_addr_e(b, bsiz, h, flags);}/**@ingroup sip_to * * Create a @b To header object with URL. * * The function sip_to_create() creates a To header object with * the given URL.   * * @param home      memory home * @param url       URL (string or pointer to url_t) * * @return * The function sip_to

⌨️ 快捷键说明

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