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

📄 sip_basic.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 5 页
字号:
    else {      memset(b, 0, len + 1);    }    h->sh_data = pl->pl_data = b;    h->sh_len = pl->pl_len = len;  }  return pl;}/* ====================================================================== *//**@SIP_HEADER sip_separator Separator Line * * An empty line separates message headers from the message body (payload). * In order to avoid modifying messages with integrity protection, the * separator line has its own header structure which is included in the * #sip_t structure. * * The parsed separator line is stored in #sip_separator_t structure. *//**@ingroup sip_separator * @typedef typedef struct sip_separator_s sip_separator_t; * * The structure #sip_separator_t contains representation of separator line * between message headers and body. * * The #sip_separator_t is defined as follows: * @code * typedef struct sip_separator_s { *   msg_common_t    sep_common[1];     // Common fragment info *   msg_header_t   *sep_next;          // Pointer to next header *   char            sep_data[4];       // NUL-terminated separator * } sip_separator_t; * @endcode */#define sip_separator_d msg_separator_d#define sip_separator_e msg_separator_e#define sip_separator_insert msg_separator_insertmsg_hclass_t sip_separator_class[] = SIP_HEADER_CLASS(separator, NULL, "", sep_common, single, any);/**@ingroup sip_separator *  * Create a @ref sip_separator "SIP separator line" structure. */sip_separator_t *sip_separator_create(su_home_t *home){  sip_separator_t *sep = (sip_separator_t *)    sip_header_alloc(home, sip_separator_class, 0);  if (sep)    strcpy(sep->sep_data, CRLF);  return sep;}/* ====================================================================== *//**@SIP_HEADER sip_unknown Unknown Headers * * The unknown headers are handled with #sip_unknown_t structure. The * unknown header name is stored in @a un_name field and the header field * following the colon is stored in @a un_value field. *  * @note It is possible to speed up parsing process by creating a parser * which does understand only a minimum number of headers. If such a parser * is used, some well-known headers are regarded as unknown and put into * list of unknown headers. *//**@ingroup sip_unknown * @typedef typedef struct sip_unknown_s sip_unknown_t; * * The structure #sip_unknown_t contains representation of unknown headers. * * The #sip_unknown_t is defined as follows: * @code * typedef struct msg_unknown_s { *   msg_common_t    un_common[1];  // Common fragment info  *   msg_unknown_t  *un_next;       // Link to next unknown header  *   char const     *un_name;       // Header name  *   char const     *un_value;      // Header field value  * } sip_unknown_t; * @endcode */#define sip_unknown_dup_xtra msg_unknown_dup_xtra #define sip_unknown_dup_one  msg_unknown_dup_one#define sip_unknown_update NULLmsg_hclass_t sip_unknown_class[] = SIP_HEADER_CLASS(unknown, "", "", un_common, append, unknown);issize_t sip_unknown_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen){  return msg_unknown_d(home, h, s, slen);}issize_t sip_unknown_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){  return msg_unknown_e(b, bsiz, h, flags);}/* ====================================================================== *//**@SIP_HEADER sip_error Erroneous Headers * * The erroneous headers are stored in #sip_error_t structure. *  * @note Other headers (like duplicate @ContentLength headers) may be put * into the list of erroneous headers (@c sip->sip_error). If the list of * erroneous headers is processed, the header type must be validated first * by calling sip_is_error() (or by other relevant tests). *//**@ingroup sip_error * @typedef typedef msg_error_t sip_error_t; * The structure #sip_error_t contains representation of error headers. * * The #sip_error_t is defined as follows: * @code * typedef struct msg_error_s { *   msg_common_t    er_common[1];  // Common fragment info  *   msg_error_t    *er_next;       // Link to next header  *   char const     *er_name;       // Name of bad header (if any) * } sip_error_t; * @endcode */msg_hclass_t sip_error_class[] =SIP_HEADER_CLASS(error, NULL, "", er_common, append, any);issize_t sip_error_d(su_home_t *home, msg_header_t *h, char *s, isize_t slen){  return 0;}issize_t sip_error_e(char b[], isize_t bsiz, msg_header_t const *h, int flags){  /* There is no way to encode an erroneous header */  return 0;}/* ====================================================================== *//* * addr           = ("To" | "t" | "From" | "f") ":"  *                  ( name-addr | addr-spec ) *( ";" addr-params ) * name-addr      = [ display-name ] "<" addr-spec ">" * addr-spec      = SIP-URL | URI * display-name   = *token | quoted-string *//**Parse @e name-addr. * * Parses <i>( name-addr | addr-spec )</i> construct on @Contact, @From, * @To, and other compatible headers. It splits the argument string in * four parts: * * @par * @e [display-name] @e addr-spec @e [parameters] @e [comment] @e [ss] * * @param home           pointer to memory home * @param inout_s        pointer to pointer to string to be parsed * @param return_display value-result parameter for @e display-name * @param return_url     value-result parameter for @e addr-spec * @param return_params  value-result paramater for @e parameters  * @param return_comment value-result parameter for @e comment * * @note After succesful call to the function @c sip_name_addr_d(), *ss * contains pointer to the first character not beloging to @e name-addr, * most probably a comma. If that character is a separator, the last parameter * may not be NUL (zero) terminated. So, after examining value of @a **ss, * the calling function @b MUST set it to NUL. * * @retval 0 if successful * @retval -1 upon an error * * @sa @From, @To, @Contact */issize_t sip_name_addr_d(su_home_t *home,			 char **inout_s,			 char const **return_display,			 url_t *return_url,			 msg_param_t const **return_params,			 char const **return_comment){  char c, *s = *inout_s;  char *display = NULL, *addr_spec = NULL;  size_t n;  if (*s == '\0')		/* Empty string */    return -1;    if (return_display && *s == '"') {    /* Quoted string */    if (msg_quoted_d(&s, &display) == -1)      return -1;    /* Now, we should have a '<' in s[0] */    if (s[0] != '<')      return -1;    s++[0] = '\0';		/* NUL terminate quoted string... */    n = strcspn(s, ">");    addr_spec = s; s += n;     if (*s) *s++ = '\0'; else return -1;  }   else {    if (return_display)       n = span_token_lws(s);    else      n = 0;    if (s[n] == '<') {      /* OK, we got a display name */      display = s; s += n + 1;       /* NUL terminate display name */      while (n > 0 && IS_LWS(display[n - 1]))	n--;      if (n > 0)	display[n] = '\0';      else 	display = "";      n = strcspn(s, ">");      addr_spec = s; s += n; if (*s) *s++ = '\0'; else return -1;    }    else {      /* addr-spec only */      addr_spec = s;      /**@sa       * Discussion about comma, semicolon and question mark in        * @RFC3261 section 20.10.       */      if (return_params)	n = strcspn(s, " \t,;?");	/* DO NOT accept ,;? in URL */      else	/* P-Asserted-Identity and friends */	n = strcspn(s, " ,"); /* DO NOT accept , in URL */      s += n;      if (IS_LWS(*s))	*s++ = '\0';    }  }  skip_lws(&s);  if (return_display)    *return_display = display;    /* Now, url may still not be NUL terminated, e.g., if    * it is like "Contact: url:foo,sip:bar,sip:zunk"   */  c = *s; *s = '\0';		/* terminate temporarily */  /* Do not accept an empty URL */  if (addr_spec[0] == '\0')    return -1;  if (url_d(return_url, addr_spec) == -1)    return -1;  *s = c;			/* return terminator */  *inout_s = s;  if (c == ';' && return_params)    if (msg_params_d(home, inout_s, return_params) == -1)      return -1;  if (**inout_s == '(' && return_comment)    if (msg_comment_d(inout_s, return_comment) == -1)      return -1;  return 0;}/**Encode @e name-addr and parameter list. * * Encodes @e name-addr headers, like @From, @To, @CallInfo, @ErrorInfo, * @Route, and @RecordRoute. * * @param b        buffer to store the encoding result * @param bsiz     size of the buffer @a b * @param flags    encoding flags * @param display  display name encoded before the @a url (may be NULL) * @param brackets if true, use always brackets around @a url * @param url      pointer to URL structure * @param params   pointer to parameter list (may be NULL) * @param comment  comment string encoded after others (may be NULL) * * @return  * Returns number of characters in encoding, excluding the * final NUL. * * @note * The encoding result may be incomplete if the buffer size is not large * enough to store the whole encoding result. */issize_t sip_name_addr_e(char b[], isize_t bsiz, 			 int flags, 			 char const *display, 			 int brackets, url_t const url[],			 msg_param_t const params[],			 char const *comment){  int const compact = MSG_IS_COMPACT(flags);  char const *u;  char *b0 = b, *end = b + bsiz;  brackets = brackets || display ||     (url && (url->url_params || 	     url->url_headers ||	     ((u = url->url_user) && u[strcspn(u, ";,?")]) ||	     ((u = url->url_password) && u[strcspn(u, ",")])));  if (display && display[0]) {    MSG_STRING_E(b, end, display);    if (!compact) MSG_CHAR_E(b, end, ' ');  }  if (url) {    if (brackets) MSG_CHAR_E(b, end, '<');    URL_E(b, end, url);    if (brackets) MSG_CHAR_E(b, end, '>');  }  MSG_PARAMS_E(b, end, params, flags);  if (comment) {    if (!compact) MSG_CHAR_E(b, end, ' ');    MSG_CHAR_E(b, end, '(');    MSG_STRING_E(b, end, comment);    MSG_CHAR_E(b, end, ')');  }  MSG_TERM_E(b, end);      return b - b0;}/** Calculate the extra size needed to duplicate a name-addr-params construct. * * @param display  display name (may be NULL) * @param addr     pointer to URL structure * @param params   pointer to parameter list (may be NULL) * @param offset   base offset * * @retval Size of duplicated name-addr-params construct, including base offset. * * @NEW_1_12_7. */isize_t sip_name_addr_xtra(char const *display, url_t const *addr,			   msg_param_t const params[],			   isize_t offset){  SIP_PARAMS_SIZE(offset, params);  offset += SIP_STRING_SIZE(display);  offset += url_xtra(addr);  return offset;}/**Duplicate a name-addr-params construct. * * @param d_display value-result parameter for copied @e name (may be NULL) * @param display   display name (may be NULL) * @param d_addr    value-result parameter for copied @e address * @param addr      pointer to URL address structure * @param d_params value-result parameter for copied parameters (may be NULL) * @param params   pointer to parameter list (may be NULL) * @param b        pointer to memory pool * @param xtra     size of the memory pool * * @retval End of the memory area used. * * @NEW_1_12_7. */char *sip_name_addr_dup(char const **d_display, char const *display,			url_t *d_addr, url_t const *addr,			msg_param_t const **d_params, msg_param_t const params[],			char *b, isize_t xtra){  char *end = b + xtra;  if (d_params)    b = msg_params_dup(d_params, params, b, xtra);  URL_DUP(b, end, d_addr, addr);  if (d_display)    MSG_STRING_DUP(b, *d_display, display);  assert(b <= end);  return b;}/** Parse @To or @From headers */static issize_t sip_addr_d(su_home_t *home,			   sip_header_t *h,			   char *s,			   isize_t slen){  sip_addr_t *a = (sip_addr_t *)h;  char const *comment = NULL;  if (sip_name_addr_d(home, 		      &s, 		      &a->a_display, 		      a->a_url, 		      &a->a_params,		      &comment) == -1       || *s /* XXX - something extra? */)    return -1;  a->a_tag = msg_params_find(a->a_params, "tag=");  return 0;}static int sip_addr_e(char b[], isize_t bsiz, sip_header_t const *h, int flags){  sip_addr_t const *a = (sip_addr_t const *)h;  return sip_name_addr_e(b, bsiz,			 flags,			 a->a_display, 			 MSG_IS_CANONIC(flags), a->a_url,			 a->a_params,			 NULL);}/** * Extra dup size of a sip_addr_t object. * * This function calculates extra size required when duplicating a * sip_addr_t object. * * @param a pointer to a sip_addr_t object * * @return *   Size of strings related to sip_addr_t object. */staticisize_t sip_addr_dup_xtra(sip_header_t const *h, isize_t offset){  sip_addr_t const *a = (sip_addr_t const *)h;  return sip_name_addr_xtra(a->a_display, 			    a->a_url,			    a->a_params,			    offset);}/**@internal * Duplicate one sip_addr_t object. */static char *sip_addr_dup_one(sip_header_t *dst, sip_header_t const *src,			      char *b, isize_t xtra){  sip_addr_t *a = (sip_addr_t *)dst;  sip_addr_t const *o = (sip_addr_t *)src;

⌨️ 快捷键说明

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