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

📄 sip_parser.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (parsing_headers) {	    if (!pj_scan_is_eof(scanner)) {		/* Skip until next line.		 * Watch for header continuation.		 */		do {		    pj_scan_skip_line(scanner);		} while (IS_SPACE(*scanner->curptr));	    }	    /* Restore flag. Flag may be set in int_parse_sip_url() */	    scanner->skip_ws = PJ_SCAN_AUTOSKIP_WS_HEADER;	    /* Continue parse next header, if any. */	    if (!pj_scan_is_eof(scanner) && !IS_NEWLINE(*scanner->curptr)) {		goto parse_headers;	    }	}	msg = NULL;    }    PJ_END;    return msg;}/* Parse parameter (pname ["=" pvalue]). */static void parse_param_imp( pj_scanner *scanner, pj_pool_t *pool,			     pj_str_t *pname, pj_str_t *pvalue,			     const pj_cis_t *spec, const pj_cis_t *esc_spec,			     unsigned option){    /* pname */    parser_get_and_unescape(scanner, pool, spec, esc_spec, pname);    /* init pvalue */    pvalue->ptr = NULL;    pvalue->slen = 0;    /* pvalue, if any */    if (*scanner->curptr == '=') {	pj_scan_get_char(scanner);	if (!pj_scan_is_eof(scanner)) {	    /* pvalue can be a quoted string. */	    if (*scanner->curptr == '"') {		pj_scan_get_quote( scanner, '"', '"', pvalue);		if (option & PJSIP_PARSE_REMOVE_QUOTE) {		    pvalue->ptr++;		    pvalue->slen -= 2;		}	    } else if(pj_cis_match(spec, *scanner->curptr)) {		parser_get_and_unescape(scanner, pool, spec, esc_spec, pvalue);	    }	}    }}/* Parse parameter (pname ["=" pvalue]) using token. */void pjsip_parse_param_imp(  pj_scanner *scanner, pj_pool_t *pool,			     pj_str_t *pname, pj_str_t *pvalue,			     unsigned option){    parse_param_imp(scanner, pool, pname, pvalue, &pjsip_TOKEN_SPEC,		    &pjsip_TOKEN_SPEC_ESC, option);}/* Parse parameter (pname ["=" pvalue]) using paramchar. */void pjsip_parse_uri_param_imp(pj_scanner *scanner, pj_pool_t *pool,			       pj_str_t *pname, pj_str_t *pvalue,			       unsigned option){    parse_param_imp(scanner, pool, pname, pvalue, &pjsip_PARAM_CHAR_SPEC,		    &pjsip_PARAM_CHAR_SPEC_ESC, option);}/* Parse parameter (";" pname ["=" pvalue]) in header. */static void int_parse_param( pj_scanner *scanner, pj_pool_t *pool,			     pj_str_t *pname, pj_str_t *pvalue,			     unsigned option){    /* Get ';' character */    pj_scan_get_char(scanner);    /* Get pname and optionally pvalue */    pjsip_parse_param_imp(scanner, pool, pname, pvalue, option);}/* Parse parameter (";" pname ["=" pvalue]) in URI. */static void int_parse_uri_param( pj_scanner *scanner, pj_pool_t *pool,				 pj_str_t *pname, pj_str_t *pvalue,				 unsigned option){    /* Get ';' character */    pj_scan_get_char(scanner);    /* Get pname and optionally pvalue */    pjsip_parse_uri_param_imp(scanner, pool, pname, pvalue, 			      option);}/* Parse header parameter. */static void int_parse_hparam( pj_scanner *scanner, pj_pool_t *pool,			      pj_str_t *hname, pj_str_t *hvalue ){    /* Get '?' or '&' character. */    pj_scan_get_char(scanner);    /* hname */    parser_get_and_unescape(scanner, pool, &pjsip_HDR_CHAR_SPEC, 			    &pjsip_HDR_CHAR_SPEC_ESC, hname);    /* Init hvalue */    hvalue->ptr = NULL;    hvalue->slen = 0;    /* pvalue, if any */    if (*scanner->curptr == '=') {	pj_scan_get_char(scanner);	if (!pj_scan_is_eof(scanner) && 	    pj_cis_match(&pjsip_HDR_CHAR_SPEC, *scanner->curptr))	{	    parser_get_and_unescape(scanner, pool, &pjsip_HDR_CHAR_SPEC,				    &pjsip_HDR_CHAR_SPEC_ESC, hvalue);	}    }}/* Parse host:port in URI. */static void int_parse_uri_host_port( pj_scanner *scanner, 				     pj_str_t *host, int *p_port){    pj_scan_get( scanner, &pjsip_HOST_SPEC, host);    /* RFC3261 section 19.1.2: host don't need to be unescaped */    if (*scanner->curptr == ':') {	pj_str_t port;	pj_scan_get_char(scanner);	pj_scan_get(scanner, &pjsip_DIGIT_SPEC, &port);	*p_port = pj_strtoul(&port);    } else {	*p_port = 0;    }}/* Determine if the next token in an URI is a user specification. */static int int_is_next_user(pj_scanner *scanner){    pj_str_t dummy;    int is_user;    /* Find character '@'. If this character exist, then the token     * must be a username.     */    if (pj_scan_peek( scanner, &pjsip_PROBE_USER_HOST_SPEC, &dummy) == '@')	is_user = 1;    else	is_user = 0;    return is_user;}/* Parse user:pass tokens in an URI. */static void int_parse_user_pass( pj_scanner *scanner, pj_pool_t *pool,				 pj_str_t *user, pj_str_t *pass){    parser_get_and_unescape(scanner, pool, &pjsip_USER_SPEC, 			    &pjsip_USER_SPEC_ESC, user);    if ( *scanner->curptr == ':') {	pj_scan_get_char( scanner );	parser_get_and_unescape(scanner, pool, &pjsip_PASSWD_SPEC,				&pjsip_PASSWD_SPEC_ESC, pass);    } else {	pass->ptr = NULL;	pass->slen = 0;    }    /* Get the '@' */    pj_scan_get_char( scanner );}/* Parse all types of URI. */static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *pool,					      unsigned opt){    pjsip_uri *uri;    int is_name_addr = 0;    /* Exhaust any whitespaces. */    pj_scan_skip_whitespace(scanner);    if (*scanner->curptr=='"' || *scanner->curptr=='<') {	uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );	is_name_addr = 1;    } else {	pj_str_t scheme;	int next_ch;	next_ch = pj_scan_peek( scanner, &pjsip_DISPLAY_SPEC, &scheme);	if (next_ch==':') {	    pjsip_parse_uri_func *func = find_uri_handler(&scheme);	    if (func == NULL) {		/* Unsupported URI scheme */		PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);	    }	    uri = (*func)( scanner, pool, 			  (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0);	} else {	    uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );	    is_name_addr = 1;	}    }    /* Should we return the URI object as name address? */    if (opt & PJSIP_PARSE_URI_AS_NAMEADDR) {	if (is_name_addr == 0) {	    pjsip_name_addr *name_addr;	    name_addr = pjsip_name_addr_create(pool);	    name_addr->uri = uri;	    uri = (pjsip_uri*)name_addr;	}    }    return uri;}/* Parse URI. */static pjsip_uri *int_parse_uri(pj_scanner *scanner, pj_pool_t *pool, 				pj_bool_t parse_params){    /* Bug:     * This function should not call back int_parse_name_addr() because     * it is called by that function. This would cause stack overflow     * with PROTOS test #1223.    if (*scanner->curptr=='"' || *scanner->curptr=='<') {	return (pjsip_uri*)int_parse_name_addr( scanner, pool );    } else {    */	pj_str_t scheme;	int colon;	pjsip_parse_uri_func *func;	/* Get scheme. */	colon = pj_scan_peek(scanner, &pjsip_TOKEN_SPEC, &scheme);	if (colon != ':') {	    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);	}	func = find_uri_handler(&scheme);	if (func)  {	    return (pjsip_uri*)(*func)(scanner, pool, parse_params);	} else {	    /* Unsupported URI scheme */	    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);	    UNREACHED({ return NULL; /* Not reached. */ })	}    /*    }    */}/* Parse "sip:" and "sips:" URI.  * This actually returns (pjsip_sip_uri*) type, */static void* int_parse_sip_url( pj_scanner *scanner, 				pj_pool_t *pool,				pj_bool_t parse_params){    pj_str_t scheme;    pjsip_sip_uri *url = NULL;    int colon;    int skip_ws = scanner->skip_ws;    scanner->skip_ws = 0;    pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &scheme);    colon = pj_scan_get_char(scanner);    if (colon != ':') {	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);    }    if (parser_stricmp(scheme, pjsip_SIP_STR)==0) {	url = pjsip_sip_uri_create(pool, 0);    } else if (parser_stricmp(scheme, pjsip_SIPS_STR)==0) {	url = pjsip_sip_uri_create(pool, 1);    } else {	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);	/* should not reach here */	UNREACHED({	    pj_assert(0);	    return 0;	})    }    if (int_is_next_user(scanner)) {	int_parse_user_pass(scanner, pool, &url->user, &url->passwd);    }    /* Get host:port */    int_parse_uri_host_port(scanner, &url->host, &url->port);    /* Get URL parameters. */    if (parse_params) {      while (*scanner->curptr == ';' ) {	pj_str_t pname, pvalue;	int_parse_uri_param( scanner, pool, &pname, &pvalue, 0);	if (!parser_stricmp(pname, pjsip_USER_STR) && pvalue.slen) {	    url->user_param = pvalue;	} else if (!parser_stricmp(pname, pjsip_METHOD_STR) && pvalue.slen) {	    url->method_param = pvalue;	} else if (!parser_stricmp(pname,pjsip_TRANSPORT_STR) && pvalue.slen) {	    url->transport_param = pvalue;	} else if (!parser_stricmp(pname, pjsip_TTL_STR) && pvalue.slen) {	    url->ttl_param = pj_strtoul(&pvalue);	} else if (!parser_stricmp(pname, pjsip_MADDR_STR) && pvalue.slen) {	    url->maddr_param = pvalue;	} else if (!parser_stricmp(pname, pjsip_LR_STR)) {	    url->lr_param = 1;	} else {	    pjsip_param *p = pj_pool_alloc(pool, sizeof(pjsip_param));	    p->name = pname;	    p->value = pvalue;	    pj_list_insert_before(&url->other_param, p);	}      }    }    /* Get header params. */    if (parse_params && *scanner->curptr == '?') {      do {	pjsip_param *param;	param = pj_pool_alloc(pool, sizeof(pjsip_param));	int_parse_hparam(scanner, pool, &param->name, &param->value);	pj_list_insert_before(&url->header_param, param);      } while (*scanner->curptr == '&');    }    scanner->skip_ws = skip_ws;    pj_scan_skip_whitespace(scanner);    return url;}/* Parse nameaddr. */static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner, 					     pj_pool_t *pool ){    int has_bracket;    pjsip_name_addr *name_addr;    name_addr = pjsip_name_addr_create(pool);    if (*scanner->curptr == '"') {	pj_scan_get_quote( scanner, '"', '"', &name_addr->display);	/* Trim the leading and ending quote */	name_addr->display.ptr++;	name_addr->display.slen -= 2;    } else if (*scanner->curptr != '<') {	int next;	pj_str_t dummy;	/* This can be either the start of display name,	 * the start of URL ("sip:", "sips:", "tel:", etc.), or '<' char.	 * We're only interested in display name, because SIP URL	 * will be parser later.	 */	next = pj_scan_peek(scanner, &pjsip_DISPLAY_SPEC, &dummy);	if (next == '<') {	    /* Ok, this is what we're looking for, a display name. */	    pj_scan_get_until_ch( scanner, '<', &name_addr->display);	    pj_strtrim(&name_addr->display);	}    }    /* Manually skip whitespace. */    pj_scan_skip_whitespace(scanner);    /* Get the SIP-URL */    has_bracket = (*scanner->curptr == '<');    if (has_bracket)	pj_scan_get_char(scanner);    name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE );    if (has_bracket) {	if (pj_scan_get_char(scanner) != '>')	    PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);    }    return name_addr;}/* Parse SIP request line. */static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool,				pjsip_request_line *req_line){    pj_str_t token;    pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &token);    pjsip_method_init_np( &req_line->method, &token);    req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE);    if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0)	PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);    pj_scan_advance_n (scanner, 7, 1);    pj_scan_get_newline( scanner );}/* Parse status line. */static void int_parse_status_line( pj_scanner *scanner, 				   pjsip_status_line *status_line){    pj_str_t token;    if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0)	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);    pj_scan_advance_n( scanner, 7, 1);    pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token);    status_line->code = pj_strtoul(&token);    pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &status_line->reason);    pj_scan_get_newline( scanner );}/* * Public API to parse SIP status line. */PJ_DEF(pj_status_t) pjsip_parse_status_line( char *buf, pj_size_t size,					     pjsip_status_line *status_line){    pj_scanner scanner;    PJ_USE_EXCEPTION;    pj_bzero(status_line, sizeof(*status_line));    pj_scan_init(&scanner, buf, size, 0, &on_syntax_error);    PJ_TRY {	int_parse_status_line(&scanner, status_line);    }     PJ_CATCH_ANY {	/* Tolerate the error if it is caused only by missing newline */	if (status_line->code == 0 && status_line->reason.slen == 0) {	    pj_scan_fini(&scanner);	    return PJSIP_EINVALIDMSG;	}    }    PJ_END;    pj_scan_fini(&scanner);    return PJ_SUCCESS;}/* Parse ending of header. */static void parse_hdr_end( pj_scanner *scanner ){    if (pj_scan_is_eof(scanner)) {	;   /* Do nothing. */    } else if (*scanner->curptr == '&') {	pj_scan_get_char(scanner);    } else {	pj_scan_get_newline(scanner);    }}/* Parse ending of header. */void pjsip_parse_end_hdr_imp( pj_scanner *scanner ){    parse_hdr_end(scanner);}/* Parse generic array header. */static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,				     pj_scanner *scanner){    /* Some header fields allow empty elements in the value:     *   Accept, Allow, Supported     */    if (pj_scan_is_eof(scanner) || 	*scanner->curptr == '\r' || *scanner->curptr == '\n')     {	goto end;    }    pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]);    hdr->count++;    while (*scanner->curptr == ',') {	pj_scan_get_char(scanner);	pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, 		     &hdr->values[hdr->count]);	hdr->count++;	if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT)	    break;    }end:

⌨️ 快捷键说明

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