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

📄 sip_parser.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 * *//**@ingroup sip_parser * @CFILE sip_parser.c * * SIP parser. * * @author Pekka Pessi <Pekka.Pessi@nokia.com>. * * @date Created: Thu Oct  5 14:01:24 2000 ppessi */#include "config.h"/* Avoid casting sip_t to msg_pub_t and sip_header_t to msg_header_t */#define MSG_PUB_T       struct sip_s#define MSG_HDR_T       union sip_header_u#include <sofia-sip/su_tagarg.h>#include "sofia-sip/sip_parser.h"#include <sofia-sip/msg_mclass.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <assert.h>#include <limits.h>#ifndef UINT32_MAX#define UINT32_MAX (0xffffffffU)#endif/** Version of the SIP module */char const sip_parser_version[] = VERSION;/** SIP version 2.0. */char const sip_version_2_0[] = "SIP/2.0";/** Default message class */extern msg_mclass_t sip_mclass[];static msg_mclass_t const *_default = sip_mclass;/** Return a built-in SIP parser object. */msg_mclass_t const *sip_default_mclass(void){  return _default;}/** Update the default SIP parser. * * Use the extended SIP parser as default one. * * If the applications want to use headers added after @VERSION_1_12_5, * they should call this function before doing any other initialization, e.g., * @code *   su_init(); *   if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) { *     su_deinit(); *     exit(2); *   } * @endcode * * The default parser is not extended because it may break the old * applications looking for extension headers from sip_unknown list. * * @retval 0 when successful * @retval -1 upon an error * * @sa sip_extend_mclass() * * @NEW_1_12_7. */int sip_update_default_mclass(msg_mclass_t const *mclass){  if (mclass == NULL)    return -1;  _default = mclass;  return 0;}/**Extend SIP parser class with extension headers. * * Extend given SIP parser class with extension headers. If the given parser * (message class) is the default one or NULL, make a clone of default * parser before extending it. * * @param input pointer to a SIP message class (may be NULL) * * @return Pointer to extended mclass, or NULL upon an error. * * @sa * @AlertInfo, * @ReplyTo, * @RemotePartyId, * @PAssertedIdentity, * @PPreferredIdentity, * @SuppressBodyIfMatch, * @SuppressNotifyIfMatch * * @NEW_1_12_7. */msg_mclass_t *sip_extend_mclass(msg_mclass_t *input){  msg_mclass_t *mclass;  if (input == NULL || input == _default)    mclass = msg_mclass_clone(_default, 0, 0);  else    mclass = input;  if (mclass) {    extern msg_hclass_t * const sip_extensions[];    int i;    for (i = 0; sip_extensions[i]; i++) {      msg_hclass_t *hclass = sip_extensions[i];      if (mclass->mc_unknown != msg_find_hclass(mclass, hclass->hc_name, NULL))	continue;      if (msg_mclass_insert_header(mclass, hclass, 0) < 0) {	if (input != mclass)	  free(mclass);	return mclass = NULL;      }    }  }  return mclass;}/** Extract the SIP message body, including separator line.  * * @param msg  message object [IN] * @param sip  public SIP message structure [IN/OUT] * @param b    buffer containing unparsed data [IN] * @param bsiz buffer size [IN] * @param eos  true if buffer contains whole message [IN] * * @retval -1 error * @retval 0  cannot proceed * @retval m  */issize_t sip_extract_body(msg_t *msg, sip_t *sip, char b[], isize_t bsiz, int eos){  ssize_t m = 0;  size_t body_len;    if (!(sip->sip_flags & MSG_FLG_BODY)) {    /* We are looking at a potential empty line */    m = msg_extract_separator(msg, (msg_pub_t *)sip, b, bsiz, eos);    if (m <= 0)      return m;    sip->sip_flags |= MSG_FLG_BODY;    b += m;    bsiz -= m;  }  if (sip->sip_content_length)    body_len = sip->sip_content_length->l_length;  else if (MSG_IS_MAILBOX(sip->sip_flags)) /* message fragments */    body_len = 0;  else if (eos)    body_len = bsiz;  else if (bsiz == 0)    return m;  else    return -1;  if (body_len == 0) {    sip->sip_flags |= MSG_FLG_COMPLETE;    return m;  }  if (m)    return m;  if (eos && body_len > bsiz) {    sip->sip_flags |= MSG_FLG_TRUNC | MSG_FLG_ERROR;    return bsiz;  }  if ((m = msg_extract_payload(msg, (msg_pub_t *)sip, 			       NULL, body_len, b, bsiz, eos)) == -1)    return -1;    sip->sip_flags |= MSG_FLG_FRAGS;  if (bsiz >= body_len)    sip->sip_flags |= MSG_FLG_COMPLETE;  return m;}/** Parse SIP version. * * Parse a SIP version string. Update the  * pointer at @a ss to first non-LWS character after the version string. * * @param ss   string to be parsed [IN/OUT] * @param ver  value result for version [OUT] * * @retval 0 when successful, * @retval -1 upon an error. */int sip_version_d(char **ss, char const **ver){  char *s = *ss;  char const *result;  size_t const version_size = sizeof(sip_version_2_0) - 1;  if (strncasecmp(s, sip_version_2_0, version_size) == 0 &&       !IS_TOKEN(s[version_size])) {    result = sip_version_2_0;    s += version_size;  }  else {    /* Version consists of two tokens, separated by / */    size_t l1 = 0, l2 = 0, n;    result = s;    l1 = span_token(s);    for (n = l1; IS_LWS(s[n]); n++);    if (s[n] == '/') {      for (n++; IS_LWS(s[n]); n++);      l2 = span_token(s + n);      n += l2;    }    if (l1 == 0 || l2 == 0)      return -1;    /* If there is extra ws between tokens, compact version */    if (n > l1 + 1 + l2) {      s[l1] = '/';      memmove(s + l1 + 1, s + n - l2, l2);      s[l1 + 1 + l2] = 0;      /* Compare again with compacted version */       if (strcasecmp(s, sip_version_2_0) == 0)	result = sip_version_2_0;    }    s += n;  }  while (IS_WS(*s)) *s++ = '\0';    *ss = s;  if (ver)     *ver = result;  return 0;}/** Calculate extra space required by version string */isize_t sip_version_xtra(char const *version){  if (version == SIP_VERSION_CURRENT)    return 0;  return MSG_STRING_SIZE(version);}/** Duplicate a transport string */void sip_version_dup(char **pp, char const **dd, char const *s){  if (s == SIP_VERSION_CURRENT)    *dd = s;  else    MSG_STRING_DUP(*pp, *dd, s);}char const sip_method_name_invite[] =  	 "INVITE";char const sip_method_name_ack[] =     	 "ACK";char const sip_method_name_cancel[] =  	 "CANCEL";char const sip_method_name_bye[] =     	 "BYE";char const sip_method_name_options[] = 	 "OPTIONS";char const sip_method_name_register[] =  "REGISTER";char const sip_method_name_info[] =      "INFO";char const sip_method_name_prack[] =     "PRACK";char const sip_method_name_update[] =    "UPDATE";char const sip_method_name_message[] =   "MESSAGE";char const sip_method_name_subscribe[] = "SUBSCRIBE";char const sip_method_name_notify[] =    "NOTIFY";char const sip_method_name_refer[] =     "REFER";char const sip_method_name_publish[] =   "PUBLISH";/** Well-known SIP method names. */char const * const sip_method_names[] = {  "<UNKNOWN>",  sip_method_name_invite,  sip_method_name_ack,  sip_method_name_cancel,  sip_method_name_bye,  sip_method_name_options,  sip_method_name_register,  sip_method_name_info,  sip_method_name_prack,  sip_method_name_update,  sip_method_name_message,  sip_method_name_subscribe,  sip_method_name_notify,  sip_method_name_refer,

⌨️ 快捷键说明

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