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

📄 sip_basic.c

📁 sip协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
  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. *//**@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 SIP separator line structure. */sip_separator_t *sip_separator_create(su_home_t *home){  sip_separator_t *sep =     sip_header_alloc(home, sip_separator_class, 0)->sh_separator;  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 whole * unknown header including its name is included in the header value string * @a g_value. *  * @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. */#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);int sip_unknown_d(su_home_t *home, sip_header_t *h, char *s, int slen){  return msg_unknown_d(home, h, s, slen);}int sip_unknown_e(char b[], int 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 @b Content-Length 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; * Type for erroneous headers. */msg_hclass_t sip_error_class[] =SIP_HEADER_CLASS(error, NULL, "", er_common, append, any);int sip_error_d(su_home_t *home, msg_header_t *h, char *s, int slen){  return 0;}int sip_error_e(char b[], int 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 @b Contact, @b From, * @b 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 comma. If that character is a separator, the last parameter * may not be NUL (zero) terminated. So, after examining value of @a **ss, * tohe calling function @b MUST set it to NUL. * * @note * Other header like @b Route or @b Route-Record may require some tweaking. * * @return  * The function @c sip_name_addr_d() returns 0 if successful, and -1 upon an * error. */int 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;  int n;  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, " ,;?");	/* 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 */  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, Call-Info, Error-Info, * Route, and Record-Route. * * @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. */int sip_name_addr_e(char b[], int 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;}/** Parse To or From headers */int sip_addr_d(su_home_t *home,	       sip_header_t *h,	       char *s,	       int 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[], int 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. */staticint sip_addr_dup_xtra(sip_header_t const *h, int offset){  int rv = offset;  sip_addr_t const *a = (sip_addr_t const *)h;  MSG_PARAMS_SIZE(rv, a->a_params);  rv += MSG_STRING_SIZE(a->a_display);  rv += url_xtra(a->a_url);      return rv;}/**@internal * Duplicate one sip_addr_t object. */static char *sip_addr_dup_one(sip_header_t *dst, sip_header_t const *src,			      char *b, int xtra){  sip_addr_t *a = (sip_addr_t *)dst;  sip_addr_t const *o = (sip_addr_t *)src;  char *end = b + xtra;  b = msg_params_dup(&a->a_params, o->a_params, b, xtra);  MSG_STRING_DUP(b, a->a_display, o->a_display);  URL_DUP(b, end, a->a_url, o->a_url);  assert(b <= end);  return b;}/** Update parameters in sip_addr_t object */static int sip_addr_update(msg_common_t *h,			   char const *name, int namelen,			   char const *value){  sip_addr_t *a = (sip_addr_t *)h;  if (name == NULL) {    a->a_tag = NULL;  }  else if (namelen == strlen("tag") && !strncasecmp(name, "tag", namelen)) {    a->a_tag = value;  }  return 0;}/** Create an address header object from URL */static sip_addr_t *sip_addr_make_url(su_home_t *home, msg_hclass_t *hc, url_string_t const *us){  int n;  sip_header_t *h;  n = url_xtra(us->us_url);  h = sip_header_alloc(home, sip_to_class, n);      if (h) {    sip_addr_t *a = h->sh_to;    char *s2 = sip_header_data(h);    if (url_dup(s2, n, a->a_url, us->us_url) == n)      return a;    su_free(home, h);  }  return NULL;}/** Add a tag to address structure. */staticint sip_addr_tag(su_home_t *home, sip_addr_t *a, char const *tag){  if (a && tag) {    msg_param_t value = strchr(tag, '=');    if (value)      value = strchr(value, '=') + 1;    else      value = tag;    if (a->a_tag) {      if (strcasecmp(a->a_tag, value) == 0)	return 0;      else	return -1;    }    if (tag == value)      tag = su_sprintf(home, "tag=%s", tag);    else      tag = su_strdup(home, tag);    if (tag)      if (msg_header_replace_param(home, a->a_common, tag) >= 0)	return 0;  }  return -1;}/* ====================================================================== *//**@SIP_HEADER sip_call_id Call-ID Header * * The @b Call-ID header uniquely identifies a particular invitation or all * registrations of a particular client. It is defined in [S10.12] as * follows: *  * @code *    Call-ID  =  ( "Call-ID" / "i" ) HCOLON callid *    callid   =  word [ "@" word ] *    word        =  1*(alphanum / "-" / "." / "!" / "%" / "*" / *                   "_" / "+" / "`" / "'" / "~" / "(" / ")" / "<" / ">" / *                   ":" / "\" / DQUOTE / "/" / "[" / "]" / "?" / "{" / "}" ) * @endcode * *//**@ingroup sip_call_id * @typedef typedef struct sip_call_id_s sip_call_id_t; * * The structure #sip_call_id_t contains representation of SIP @b Call-ID * header. * * The #sip_call_id_t is defined as follows:

⌨️ 快捷键说明

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