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

📄 rtsp_resp.c

📁 嵌入式系统中c程序实现了rtsp协议的基本内容
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
* 
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
* 
* The Original Code is MPEG4IP.
* 
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
* 
* Contributor(s): 
*              Bill May        wmay@cisco.com
*/
/*
* rtsp_resp.c - process rtsp response
*/

#include "rtsp_private.h"
#define MIN(a,b) (a<b)? a : b

static const char *end2 = "\n\r";
static const char *end1 = "\r\n";
static const char *end3 = "\r";
static const char *end4 = "\n";

/*
* find_end_seperator()
* Will search through the string pointer to by ptr, and figure out
* what character is being used as a seperator - either \r \n, \r\n
* or \n\r.
*
* Inputs:
*    ptr - string to decode
*    len - pointer to end seperator len
*
* Outputs:
*    pointer to character to use as end seperator.  Dividing the len
*    by 2, and adding to the return pointer will give the normal
*    line seperator.
*/
static const char *find_seperator (const char *ptr)
{
	while (*ptr != '\0') {
		if (*ptr == '\r') {
			if (*(ptr + 1) == '\n') {
				return (end1);
			} else {
				return (end3);
			}
		} else if (*ptr == '\n') {
			if (*(ptr + 1) == '\r') {
				return (end2);
			} else {
				return (end4);
			}
		}
		ptr++;
	}
	return (NULL);
}
int strncasecmp(const char * s1,const char* s2,uint32_t size)
{
    char * s1tmp;
    char * s2tmp;
    int dif=0,i;
    s1tmp=(char *)Rtsp_Malloc(size,__LINE__,__FILE__);
    s2tmp=(char *)Rtsp_Malloc(size,__LINE__,__FILE__);
    for(i=0;i<size;i++) 
    {
        s1tmp[i]=tolower(s1[i]);
        s2tmp[i]=tolower(s2[i]);
    }
    dif=strncmp(s1tmp,s2tmp,size);
    Rtsp_Free(s1tmp,__LINE__,__FILE__);
    Rtsp_Free(s2tmp,__LINE__,__FILE__);
    return dif;    
}

/************************************************************************
* Decode rtsp header lines.
*
* These routines will decode the various RTSP header lines, setting the
* correct information in the rtsp_decode_t structure.
*
* DEC_DUP_WARN macro will see if the field is already set, and send a warning
* if it is.  If the cont_line field is set, it will append the next line
*
************************************************************************/
#define RTSP_HEADER_FUNC(a) static void a (const char *lptr, rtsp_decode_t *dec, int cont_line)

static void dec_dup_warn (char **location,
						  const char *lptr,
						  const char *warn,
						  int cont_line)
{
	if (*location == NULL)
	{	
		*location =(char*) strdup(lptr);
		Rtsp_Printf("location=%s\n",*location);
	} else if (cont_line != 0) {
		uint32_t len = strlen(*location);
		len += strlen(lptr);
		len++;
		*location = realloc(*location, len);
		strcat(*location, lptr);
	} else {
	/*   Rtsp_Printf( "2nd %s %s\n", warn, lptr);
		*/
	}
}

#define DEC_DUP_WARN(a, b) dec_dup_warn(&dec->a, lptr, b, cont_line)

RTSP_HEADER_FUNC(rtsp_header_allow_public)
{
	DEC_DUP_WARN(allow_public, "allow public");
}

RTSP_HEADER_FUNC(rtsp_header_connection)
{
	if (strncasecmp(lptr, "close", strlen("close")) == 0) {
		dec->close_connection = TRUE;
	}
}

RTSP_HEADER_FUNC(rtsp_header_cookie)
{
	DEC_DUP_WARN(cookie, "cookie");
}

RTSP_HEADER_FUNC(rtsp_header_content_base)
{
	DEC_DUP_WARN(content_base, "Content-Base");
}

RTSP_HEADER_FUNC(rtsp_header_content_length)
{
	dec->content_length = (uint32_t)strtoul(lptr, NULL, 10);
}

RTSP_HEADER_FUNC(rtsp_header_content_loc)
{
	DEC_DUP_WARN(content_location, "Content-Location");
}

RTSP_HEADER_FUNC(rtsp_header_content_type)
{
	DEC_DUP_WARN(content_type, "Content-Type");
}

RTSP_HEADER_FUNC(rtsp_header_cseq)
{
	dec->cseq = (uint32_t)strtoul(lptr, NULL, 10);
}

RTSP_HEADER_FUNC(rtsp_header_location)
{
	DEC_DUP_WARN(location, "Location");
}

RTSP_HEADER_FUNC(rtsp_header_range)
{
	DEC_DUP_WARN(range, "Range");
}

RTSP_HEADER_FUNC(rtsp_header_retry_after)
{
	/* May try strptime if we need to convert*/
	DEC_DUP_WARN(retry_after, "Retry-After");
}

RTSP_HEADER_FUNC(rtsp_header_rtp)
{
	DEC_DUP_WARN(rtp_info, "RtpInfo");
}

RTSP_HEADER_FUNC(rtsp_header_session)
{
	DEC_DUP_WARN(session, "Session");
}

RTSP_HEADER_FUNC(rtsp_header_speed)
{
	DEC_DUP_WARN(speed, "Speed");
}

RTSP_HEADER_FUNC(rtsp_header_transport)
{
	DEC_DUP_WARN(transport, "Transport");
}

RTSP_HEADER_FUNC(rtsp_header_www)
{
	DEC_DUP_WARN(www_authenticate, "WWW-Authenticate");
}

RTSP_HEADER_FUNC(rtsp_header_accept)
{
	DEC_DUP_WARN(accept, "Accept");
}

RTSP_HEADER_FUNC(rtsp_header_accept_enc)
{
	DEC_DUP_WARN(accept_encoding, "Accept-Encoding");
}

RTSP_HEADER_FUNC(rtsp_header_accept_lang)
{
	DEC_DUP_WARN(accept_language, "Accept-Language");
}

RTSP_HEADER_FUNC(rtsp_header_auth)
{
	DEC_DUP_WARN(authorization, "Authorization");
}

RTSP_HEADER_FUNC(rtsp_header_bandwidth)
{
	DEC_DUP_WARN(bandwidth, "Bandwidth");
}

RTSP_HEADER_FUNC(rtsp_header_blocksize)
{
	DEC_DUP_WARN(blocksize, "blocksize");
}

RTSP_HEADER_FUNC(rtsp_header_cache_control)
{
	DEC_DUP_WARN(cache_control, "Cache-control:");
}

RTSP_HEADER_FUNC(rtsp_header_content_enc)
{
	DEC_DUP_WARN(content_encoding, "Content-Encoding:");
}

RTSP_HEADER_FUNC(rtsp_header_content_lang)
{
	DEC_DUP_WARN(content_language, "Content-Language:");
}
RTSP_HEADER_FUNC(rtsp_header_date)
{
	DEC_DUP_WARN(date, "Date:");
}

RTSP_HEADER_FUNC(rtsp_header_expires)
{
	DEC_DUP_WARN(expires, "Expires:");
}

RTSP_HEADER_FUNC(rtsp_header_from)
{
	DEC_DUP_WARN(from, "From:");
}

RTSP_HEADER_FUNC(rtsp_header_ifmod)
{
	DEC_DUP_WARN(if_modified_since, "If-Modified-Since:");
}

RTSP_HEADER_FUNC(rtsp_header_lastmod)
{
	DEC_DUP_WARN(last_modified, "Last-Modified:");
}

RTSP_HEADER_FUNC(rtsp_header_proxyauth)
{
	DEC_DUP_WARN(proxy_authenticate, "Proxy-Authenticate:");
}

RTSP_HEADER_FUNC(rtsp_header_proxyreq)
{
	DEC_DUP_WARN(proxy_require, "Proxy-Require:");
}

RTSP_HEADER_FUNC(rtsp_header_referer)
{
	DEC_DUP_WARN(referer, "Referer:");
}

RTSP_HEADER_FUNC(rtsp_header_scale)
{
	DEC_DUP_WARN(scale, "Scale:");
}

RTSP_HEADER_FUNC(rtsp_header_server)
{
	DEC_DUP_WARN(server, "Server:");
}

RTSP_HEADER_FUNC(rtsp_header_unsup)
{
	DEC_DUP_WARN(unsupported, "Unsupported:");
}

RTSP_HEADER_FUNC(rtsp_header_uagent)
{
	DEC_DUP_WARN(user_agent, "User-Agent:");
}

RTSP_HEADER_FUNC(rtsp_header_via)
{
	DEC_DUP_WARN(via, "Via:");
}

/*
* header_types structure will provide a lookup between certain headers
* in RTSP, and the function routines (above) that deal with actions based
* on the response
*/
static struct {
	const char *val;
	uint32_t val_length;
	void (*parse_routine)(const char *lptr, rtsp_decode_t *decode, int cont_line);
} header_types[] =
{
#define HEAD_TYPE(a, b) { a, sizeof(a), b }
	HEAD_TYPE("Allow:", rtsp_header_allow_public),
		HEAD_TYPE("Public:", rtsp_header_allow_public),
		HEAD_TYPE("Connection:", rtsp_header_connection),
		HEAD_TYPE("Content-Base:", rtsp_header_content_base),
		HEAD_TYPE("Content-Length:", rtsp_header_content_length),
		HEAD_TYPE("Content-Location:", rtsp_header_content_loc),
		HEAD_TYPE("Content-Type:", rtsp_header_content_type),
		HEAD_TYPE("CSeq:", rtsp_header_cseq),
		HEAD_TYPE("Location:", rtsp_header_location),
		HEAD_TYPE("Range:", rtsp_header_range),
		HEAD_TYPE("Retry-After:", rtsp_header_retry_after),
		HEAD_TYPE("RTP-Info:", rtsp_header_rtp),
		HEAD_TYPE("Session:", rtsp_header_session),
		HEAD_TYPE("Set-Cookie:", rtsp_header_cookie),
		HEAD_TYPE("Speed:", rtsp_header_speed),
		HEAD_TYPE("Transport:", rtsp_header_transport),
		HEAD_TYPE("WWW-Authenticate:", rtsp_header_www),
		/* None of these are needed for client, but are included for completion*/
		HEAD_TYPE("Accept:", rtsp_header_accept),
		HEAD_TYPE("Accept-Encoding:", rtsp_header_accept_enc),
		HEAD_TYPE("Accept-Language:", rtsp_header_accept_lang),
		HEAD_TYPE("Authorization:", rtsp_header_auth),
		HEAD_TYPE("Bandwidth:", rtsp_header_bandwidth),
		HEAD_TYPE("Blocksize:", rtsp_header_blocksize),
		HEAD_TYPE("Cache-Control:", rtsp_header_cache_control),
		HEAD_TYPE("Content-Encoding:", rtsp_header_content_enc),
		HEAD_TYPE("Content-Language:", rtsp_header_content_lang),
		HEAD_TYPE("Date:", rtsp_header_date),
		HEAD_TYPE("Expires:", rtsp_header_expires),
		HEAD_TYPE("From:", rtsp_header_from),
		HEAD_TYPE("If-Modified-Since:", rtsp_header_ifmod),
		HEAD_TYPE("Last-Modified:", rtsp_header_lastmod),
		HEAD_TYPE("Proxy-Authenticate:", rtsp_header_proxyauth),
		HEAD_TYPE("Proxy-Require:", rtsp_header_proxyreq),
		HEAD_TYPE("Referer:", rtsp_header_referer),
		HEAD_TYPE("Scale:", rtsp_header_scale),
		HEAD_TYPE("Server:", rtsp_header_server),
		HEAD_TYPE("Unsupported:", rtsp_header_unsup),
		HEAD_TYPE("User-Agent:", rtsp_header_uagent),
		HEAD_TYPE("Via:", rtsp_header_via),
	{ NULL, 0, NULL },
};

/* We don't care about the following: Cache-control, date, expires,*/
/* Last-modified, Server, Unsupported, Via*/

/*
* rtsp_decode_header - header line pointed to by lptr.  will be \0 terminated
* Decode using above table
*/
static void rtsp_decode_header (const char *lptr,
								rtsp_client_t *info,
								int *last_number)
{
	int ix;
	const char *after;
	
	ix = 0;
	/*
	* go through above array, looking for a complete match
	*/
	while (header_types[ix].val != NULL) 
	{
		if (strncasecmp(lptr,
			header_types[ix].val,
			header_types[ix].val_length - 1) == 0)
		{
			after = lptr + header_types[ix].val_length;
			
			ADV_SPACE(after);
			/*
			* Call the correct parsing routine
			*/
			(header_types[ix].parse_routine)(after, info->decode_response, 0);
			*last_number = ix;

⌨️ 快捷键说明

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