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

📄 sip_basic.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 5 页
字号:
 * @retval -1 upon an error. */int sip_from_tag(su_home_t *home, sip_from_t *from, char const *tag){  return sip_addr_tag(home, from, tag);}int sip_to_tag(su_home_t *home, sip_to_t *to, char const *tag){  return sip_addr_tag(home, to, tag);}/* ====================================================================== *//**@SIP_HEADER sip_max_forwards Max-Forwards Header * * The Max-Forwards header is used to limit the number of proxies or * gateways that can forward the request.  The Max-Forwards syntax is * defined in @RFC3261 as follows: *  * @code *    Max-Forwards  =  "Max-Forwards" HCOLON 1*DIGIT * @endcode * * * The parsed Max-Forwards header is stored in #sip_max_forwards_t structure. *//**@ingroup sip_max_forwards * @typedef typedef struct sip_max_forwards_s sip_max_forwards_t; * * The structure #sip_max_forwards_t contains representation of SIP * @MaxForwards header. * * The #sip_max_forwards_t is defined as follows: * @code * typedef struct sip_max_forwards_s { *   sip_common_t        mf_common[1];  // Common fragment info *   sip_error_t        *mf_next;       // Link to next (dummy) *   unsigned long       mf_count;      // Digits * } sip_max_forwards_t; * @endcode */msg_hclass_t sip_max_forwards_class[] = SIP_HEADER_CLASS(max_forwards, "Max-Forwards", "", mf_common, 		 single, any);issize_t sip_max_forwards_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){  return sip_numeric_d(home, h, s, slen);}issize_t sip_max_forwards_e(char b[], isize_t bsiz, sip_header_t const *h, int f){  assert(sip_is_max_forwards(h));  return sip_numeric_e(b, bsiz, h, f);}/* ====================================================================== *//**@SIP_HEADER sip_min_expires Min-Expires Header * * The Min-Expires header is used to limit the number of proxies or * gateways that can forward the request.  The Min-Expires syntax is * defined in @RFC3261 as follows: *  * @code *    Min-Expires  =  "Min-Expires" HCOLON delta-seconds * @endcode * * The parsed Min-Expires header is stored in #sip_min_expires_t structure. *//**@ingroup sip_min_expires * @typedef typedef struct sip_min_expires_s sip_min_expires_t; * * The structure #sip_min_expires_t contains representation of SIP * @MinExpires header. * * The #sip_min_expires_t is defined as follows: * @code * typedef struct sip_min_expires_s { *   sip_common_t        me_common[1];  // Common fragment info *   sip_error_t        *me_next;       // Link to next (dummy) *   unsigned long       me_delta;      // Seconds * } sip_min_expires_t; * @endcode */msg_hclass_t sip_min_expires_class[] = SIP_HEADER_CLASS(min_expires, "Min-Expires", "", me_common, 		 single, any);issize_t sip_min_expires_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){  return sip_numeric_d(home, h, s, slen);}issize_t sip_min_expires_e(char b[], isize_t bsiz, sip_header_t const *h, int f){  assert(sip_is_min_expires(h));  return sip_numeric_e(b, bsiz, h, f);}/* ====================================================================== *//**@SIP_HEADER sip_retry_after Retry-After Header *  * The Retry-After response-header field @RFC3261 section 20.33 can be used to * indicate how long the service is expected to be unavailable or when the * called party anticipates being available again. Its syntax is defined in * @RFC3261 as follows: *  * @code *      Retry-After  =  "Retry-After" HCOLON delta-seconds *                      [ comment ] *( SEMI retry-param ) *      retry-param  =  ("duration" EQUAL delta-seconds) *                      / generic-param * @endcode * * The parsed Retry-After header is stored in #sip_retry_after_t structure. *//**@ingroup sip_retry_after * @typedef struct sip_retry_after_s sip_retry_after_t;  * * The structure #sip_retry_after_t contains representation of an  * @RetryAfter header. * * The #sip_retry_after_t is defined as follows: * @code * typedef struct sip_retry_after_s { *   sip_common_t        af_common[1]; // Common fragment info *   sip_error_t        *af_next;      // Link to next (dummy) *   sip_time_t          af_delta;     // Seconds to before retry *   char const         *af_comment;   // Comment string *   msg_param_t const  *af_params;    // List of parameters *   char const         *af_duration;  // Duration parameter * } sip_retry_after_t; * @endcode */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);issize_t sip_retry_after_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){  sip_retry_after_t *af = (sip_retry_after_t *)h;  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;}issize_t sip_retry_after_e(char b[], isize_t bsiz, sip_header_t const *h, int f){  sip_retry_after_t const *af = (sip_retry_after_t *)h;  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;}isize_t sip_retry_after_dup_xtra(sip_header_t const *h, isize_t offset){  sip_retry_after_t const *af = (sip_retry_after_t *)h;  MSG_PARAMS_SIZE(offset, af->af_params);  offset += MSG_STRING_SIZE(af->af_comment);  return offset;}char *sip_retry_after_dup_one(sip_header_t *dst,			      sip_header_t const *src,			      char *b,			      isize_t xtra){  sip_retry_after_t *af = (sip_retry_after_t *)dst;  sip_retry_after_t const *o = (sip_retry_after_t *)src;  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); (void)end;  return b;}static int sip_retry_after_update(msg_common_t *h,				  char const *name, isize_t 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 or a @RecordRoute header. * * @retval 0 when successful,  * @retval -1 upon an error. */issize_t sip_any_route_d(su_home_t *home,			 sip_header_t *h,			 char *s,			 isize_t slen){  sip_route_t *r = (sip_route_t *)h;  assert(h);  while (*s == ',')   /* Ignore empty entries (comma-whitespace) */    *s = '\0', s += span_lws(s + 1) + 1;  if (sip_name_addr_d(home, &s, &r->r_display, 		      r->r_url, &r->r_params, NULL) < 0)    return -1;  return msg_parse_next_field(home, h, s, slen);}issize_t sip_any_route_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){  sip_route_t const *r = (sip_route_t *)h;  return sip_name_addr_e(b, bsiz, flags, 			 r->r_display, 1, r->r_url, r->r_params, NULL);}isize_t sip_any_route_dup_xtra(sip_header_t const *h, isize_t offset){  sip_route_t const *r = (sip_route_t *)h;  return sip_name_addr_xtra(r->r_display, 			    r->r_url,			    r->r_params,			    offset);}char *sip_any_route_dup_one(sip_header_t *dst, sip_header_t const *src,			    char *b,			    isize_t xtra){  sip_route_t *r = (sip_route_t *)dst;  sip_route_t const *o = (sip_route_t *)src;  return sip_name_addr_dup(&r->r_display, o->r_display,			   r->r_url, o->r_url,			   &r->r_params, o->r_params,			   b, xtra);}#define sip_any_route_update NULL/** Create a route.  * * Create 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];   size_t 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 = (sip_record_route_t *)h)) {    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 @RFC3261 as follows: *  * @code *    Route        =  "Route" HCOLON route-param *(COMMA route-param) *    route-param  =  name-addr *( SEMI rr-param ) * @endcode * * The parsed Route header is stored in #sip_route_t structure. *//**@ingroup sip_route * @typedef typedef struct sip_route_s sip_route_t; * * The structure #sip_route_t contains representation of SIP @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);issize_t sip_route_d(su_home_t *home,		     sip_header_t *h,		     char *s,		     isize_t slen){  return sip_any_route_d(home, h, s, slen);}issize_t sip_route_e(char b[], isize_t 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 @Route header object. * * 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 * Returns a pointer to newly created @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 @RFC3261 * 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 * * The parsed Record-Route header is stored in #sip_record_route_t structure. *//**@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 * @RecordRoute header. * * The #sip_record_route_t is defined as follows: * @code * typedef struct sip_route_s { *   sip_common_t

⌨️ 快捷键说明

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