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

📄 sip_uri.c

📁 基于sip协议的网络电话源码
💻 C
字号:
/* $Id: sip_uri.c 1222 2007-04-29 06:30:58Z bennylp $ *//*  * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  */#include <pjsip/sip_uri.h>#include <pjsip/sip_msg.h>#include <pjsip/sip_parser.h>#include <pjsip/print_util.h>#include <pjsip/sip_errno.h>#include <pjlib-util/string.h>#include <pj/string.h>#include <pj/pool.h>#include <pj/assert.h>/* * Generic parameter manipulation. */PJ_DEF(pjsip_param*) pjsip_param_find(  pjsip_param *param_list,					const pj_str_t *name ){    pjsip_param *p = param_list->next;    while (p != param_list) {	if (pj_stricmp(&p->name, name)==0)	    return p;	p = p->next;    }    return NULL;}PJ_DEF(const pjsip_param*) pjsip_param_cfind( const pjsip_param *param_list,					      const pj_str_t *name ){    const pjsip_param *p = param_list->next;    while (p != param_list) {	if (pj_stricmp_alnum(&p->name, name)==0)	    return p;	p = p->next;    }    return NULL;}PJ_DEF(void) pjsip_param_clone( pj_pool_t *pool, pjsip_param *dst_list,				const pjsip_param *src_list){    const pjsip_param *p = src_list->next;    pj_list_init(dst_list);    while (p != src_list) {	pjsip_param *new_param = pj_pool_alloc(pool, sizeof(pjsip_param));	pj_strdup(pool, &new_param->name, &p->name);	pj_strdup(pool, &new_param->value, &p->value);	pj_list_insert_before(dst_list, new_param);	p = p->next;    }}PJ_DEF(void) pjsip_param_shallow_clone( pj_pool_t *pool, 					pjsip_param *dst_list,					const pjsip_param *src_list){    const pjsip_param *p = src_list->next;    pj_list_init(dst_list);    while (p != src_list) {	pjsip_param *new_param = pj_pool_alloc(pool, sizeof(pjsip_param));	new_param->name = p->name;	new_param->value = p->value;	pj_list_insert_before(dst_list, new_param);	p = p->next;    }}PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,					 char *buf, pj_size_t size,					 const pj_cis_t *pname_spec,					 const pj_cis_t *pvalue_spec,					 int sep){    const pjsip_param *p;    char *startbuf;    char *endbuf;    int printed;    p = param_list->next;    if (p == param_list)	return 0;    startbuf = buf;    endbuf = buf + size;    PJ_UNUSED_ARG(pname_spec);    do {	*buf++ = (char)sep;	copy_advance_escape(buf, p->name, (*pname_spec));	if (p->value.slen) {	    *buf++ = '=';	    if (*p->value.ptr == '"')		copy_advance(buf, p->value);	    else		copy_advance_escape(buf, p->value, (*pvalue_spec));	}	p = p->next;	if (sep == '?') sep = '&';    } while (p != param_list);    return buf-startbuf;}/* * URI stuffs */#define IS_SIPS(url)	((url)->vptr==&sips_url_vptr)static const pj_str_t *pjsip_url_get_scheme( const pjsip_sip_uri* );static const pj_str_t *pjsips_url_get_scheme( const pjsip_sip_uri* );static const pj_str_t *pjsip_name_addr_get_scheme( const pjsip_name_addr * );static void *pjsip_get_uri( pjsip_uri *uri );static void *pjsip_name_addr_get_uri( pjsip_name_addr *name );static pj_str_t sip_str = { "sip", 3 };static pj_str_t sips_str = { "sips", 4 };#ifdef __GNUC__#  define HAPPY_FLAG	(void*)#else#  define HAPPY_FLAG#endifstatic pjsip_name_addr* pjsip_name_addr_clone( pj_pool_t *pool, 					       const pjsip_name_addr *rhs);static pj_ssize_t pjsip_name_addr_print(pjsip_uri_context_e context,					const pjsip_name_addr *name, 					char *buf, pj_size_t size);static int pjsip_name_addr_compare(  pjsip_uri_context_e context,				     const pjsip_name_addr *naddr1,				     const pjsip_name_addr *naddr2);static pj_ssize_t pjsip_url_print(  pjsip_uri_context_e context,				    const pjsip_sip_uri *url, 				    char *buf, pj_size_t size);static int pjsip_url_compare( pjsip_uri_context_e context,			      const pjsip_sip_uri *url1, 			      const pjsip_sip_uri *url2);static pjsip_sip_uri* pjsip_url_clone(pj_pool_t *pool, 				      const pjsip_sip_uri *rhs);static pjsip_uri_vptr sip_url_vptr = {    HAPPY_FLAG &pjsip_url_get_scheme,    HAPPY_FLAG &pjsip_get_uri,    HAPPY_FLAG &pjsip_url_print,    HAPPY_FLAG &pjsip_url_compare,    HAPPY_FLAG &pjsip_url_clone};static pjsip_uri_vptr sips_url_vptr = {    HAPPY_FLAG &pjsips_url_get_scheme,    HAPPY_FLAG &pjsip_get_uri,    HAPPY_FLAG &pjsip_url_print,    HAPPY_FLAG &pjsip_url_compare,    HAPPY_FLAG &pjsip_url_clone};static pjsip_uri_vptr name_addr_vptr = {    HAPPY_FLAG &pjsip_name_addr_get_scheme,    HAPPY_FLAG &pjsip_name_addr_get_uri,    HAPPY_FLAG &pjsip_name_addr_print,    HAPPY_FLAG &pjsip_name_addr_compare,    HAPPY_FLAG &pjsip_name_addr_clone};static const pj_str_t *pjsip_url_get_scheme(const pjsip_sip_uri *url){    PJ_UNUSED_ARG(url);    return &sip_str;}static const pj_str_t *pjsips_url_get_scheme(const pjsip_sip_uri *url){    PJ_UNUSED_ARG(url);    return &sips_str;}static void *pjsip_get_uri( pjsip_uri *uri ){    return uri;}static void *pjsip_name_addr_get_uri( pjsip_name_addr *name ){    return pjsip_uri_get_uri(name->uri);}PJ_DEF(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *url, 				       pj_bool_t secure ){    url->vptr = secure ? &sips_url_vptr : &sip_url_vptr;}PJ_DEF(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure){    pj_bzero(url, sizeof(*url));    url->ttl_param = -1;    pjsip_sip_uri_set_secure(url, secure);    pj_list_init(&url->other_param);    pj_list_init(&url->header_param);}PJ_DEF(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, 					     pj_bool_t secure ){    pjsip_sip_uri *url = pj_pool_alloc(pool, sizeof(pjsip_sip_uri));    pjsip_sip_uri_init(url, secure);    return url;}static pj_ssize_t pjsip_url_print(  pjsip_uri_context_e context,				    const pjsip_sip_uri *url, 				    char *buf, pj_size_t size){    int printed;    char *startbuf = buf;    char *endbuf = buf+size;    const pj_str_t *scheme;    *buf = '\0';    /* Print scheme ("sip:" or "sips:") */    scheme = pjsip_uri_get_scheme(url);    copy_advance_check(buf, *scheme);    *buf++ = ':';    /* Print "user:password@", if any. */    if (url->user.slen) {	copy_advance_escape(buf, url->user, pjsip_USER_SPEC);	if (url->passwd.slen) {	    *buf++ = ':';	    copy_advance_escape(buf, url->passwd, pjsip_PASSWD_SPEC);	}	*buf++ = '@';    }    /* Print host. */    pj_assert(url->host.slen != 0);    copy_advance_check(buf, url->host);    /* Only print port if it is explicitly specified.      * Port is not allowed in To and From header.     */    /* Unfortunately some UA requires us to send back the port     * number exactly as it was sent. We don't remember whether an     * UA has sent us port, so we'll just send the port indiscrimately     */    //PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER)    if (url->port && context != PJSIP_URI_IN_FROMTO_HDR) {	if (endbuf - buf < 10)	    return -1;	*buf++ = ':';	printed = pj_utoa(url->port, buf);	buf += printed;    }    /* User param is allowed in all contexes */    copy_advance_pair_check(buf, ";user=", 6, url->user_param);    /* Method param is only allowed in external/other context. */    if (context == PJSIP_URI_IN_OTHER) {	copy_advance_pair_escape(buf, ";method=", 8, url->method_param, 				 pjsip_PARAM_CHAR_SPEC);    }    /* Transport is not allowed in From/To header. */    if (context != PJSIP_URI_IN_FROMTO_HDR) {	copy_advance_pair_escape(buf, ";transport=", 11, url->transport_param,				 pjsip_PARAM_CHAR_SPEC);    }    /* TTL param is not allowed in From, To, Route, and Record-Route header. */    if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&	context != PJSIP_URI_IN_ROUTING_HDR)     {	if (endbuf - buf < 15)	    return -1;	pj_memcpy(buf, ";ttl=", 5);	printed = pj_utoa(url->ttl_param, buf+5);	buf += printed + 5;    }    /* maddr param is not allowed in From and To header. */    if (context != PJSIP_URI_IN_FROMTO_HDR) {	copy_advance_pair_escape(buf, ";maddr=", 7, url->maddr_param,				 pjsip_PARAM_CHAR_SPEC);    }    /* lr param is not allowed in From, To, and Contact header. */    if (url->lr_param && context != PJSIP_URI_IN_FROMTO_HDR &&	context != PJSIP_URI_IN_CONTACT_HDR)     {	pj_str_t lr = { ";lr", 3 };	if (endbuf - buf < 3)	    return -1;	copy_advance_check(buf, lr);    }    /* Other param. */    printed = pjsip_param_print_on(&url->other_param, buf, endbuf-buf, 				   &pjsip_PARAM_CHAR_SPEC, 				   &pjsip_PARAM_CHAR_SPEC, ';');    if (printed < 0)	return -1;    buf += printed;    /* Header param.      * Header param is only allowed in these contexts:     *	- PJSIP_URI_IN_CONTACT_HDR     *	- PJSIP_URI_IN_OTHER     */    if (context == PJSIP_URI_IN_CONTACT_HDR || context == PJSIP_URI_IN_OTHER) {	printed = pjsip_param_print_on(&url->header_param, buf, endbuf-buf,				       &pjsip_HDR_CHAR_SPEC, 				       &pjsip_HDR_CHAR_SPEC, '?');	if (printed < 0)	    return -1;	buf += printed;    }    *buf = '\0';    return buf-startbuf;}static pj_status_t pjsip_url_compare( pjsip_uri_context_e context,				      const pjsip_sip_uri *url1, 				      const pjsip_sip_uri *url2){    const pjsip_param *p1;    /*     * Compare two SIP URL's according to Section 19.1.4 of RFC 3261.     */    /* SIP and SIPS URI are never equivalent.      * Note: just compare the vptr to avoid string comparison.      *       Pretty neat huh!!     */    if (url1->vptr != url2->vptr)	return PJSIP_ECMPSCHEME;    /* Comparison of the userinfo of SIP and SIPS URIs is case-sensitive.      * This includes userinfo containing passwords or formatted as      * telephone-subscribers.     */    if (pj_strcmp(&url1->user, &url2->user) != 0)	return PJSIP_ECMPUSER;    if (pj_strcmp(&url1->passwd, &url2->passwd) != 0)	return PJSIP_ECMPPASSWD;        /* Comparison of all other components of the URI is     * case-insensitive unless explicitly defined otherwise.     */    /* The ordering of parameters and header fields is not significant      * in comparing SIP and SIPS URIs.     */    /* Characters other than those in the 搑eserved

⌨️ 快捷键说明

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