/** 
 * @brief - Decoding string line as a status line
 * 
 * @param p_start_line
 * @param rtsp_msg_buffer
 * @param rtsp_msg_len
 * 
 * @return 
 */
static inline rtsp_error_t rtsp_parse_status_line(rtsp_start_line_t *p_start_line,const char *rtsp_msg_buffer, int32_t rtsp_msg_len , const char **endptr){

	const char *parse_string = NULL, *end = NULL, *temp = NULL;
	rtsp_error_t e_ret_val = RTSP_E_FAILURE;

	if(!p_start_line || !rtsp_msg_buffer || rtsp_msg_len <= 0){
		return (RTSP_E_INVALID_ARG);
	}
	/* R[7.1]
	 * Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
	 * Allowing multiple SP since RFC Text R[7.1] suggests
	 */

	parse_string = rtsp_msg_buffer;
	end = rtsp_msg_buffer + rtsp_msg_len;
	/* RTSP-Version */
	e_ret_val = rtsp_get_version(&p_start_line->version, parse_string, rtsp_msg_len, &parse_string);

	switch (e_ret_val){
	case RTSP_E_SUCCESS:
		/* Found Version String  Start Hence it is status line */ 
		p_start_line->msg_type = RTSP_MSG_RESPONSE;

		/* SP */
		temp = skip_SP(parse_string, end);
		if((NULL == temp) || (temp==parse_string)){
			/* No spaces */
			e_ret_val = RTSP_E_FAILURE;
		}else if(temp == end){
			/* Only spaces till end */
			e_ret_val = RTSP_E_INCOMPLETE;
			break;
		}
		parse_string = temp;

		/* Status-Code */
		if((parse_string + RTSP_STATUS_CODE_LEN) <= end){
			if(0 == (p_start_line->response.status_code = RTSP_STATUS_CODE(parse_string))){
				e_ret_val = RTSP_E_FAILURE;
				break;
			}
		} else {
			e_ret_val = RTSP_E_INCOMPLETE;
			break;
		}
		parse_string += RTSP_STATUS_CODE_LEN;

		/* SP */
		temp = skip_SP(parse_string, end);
		if((NULL == temp) || (temp==parse_string)){
			/* No spaces */
			e_ret_val = RTSP_E_FAILURE;
		}else if(temp==end){
			/* Only spaces till end */
			e_ret_val = RTSP_E_INCOMPLETE;
			break;
		}
		parse_string = temp;

		/* Reason-Phrase */

		p_start_line->response.reason_phrase = parse_string;
		while((parse_string <= end) && is_text(*parse_string))
			parse_string++;
			;
		/* CRLF */
		if((parse_string+1) <= end){
			if(RTSP_CR == *parse_string++ && RTSP_LF ==*parse_string++){
				p_start_line->response.reason_len = (int32_t)((rtsp_msg_buffer - parse_string)+ rtsp_msg_len);
			} else {
				e_ret_val = RTSP_E_FAILURE;
				break;
			}
		} else {
			e_ret_val = RTSP_E_INCOMPLETE;
			break;
		}

		if(endptr)
			*endptr = parse_string;
		e_ret_val = RTSP_E_SUCCESS;
		break;
	case RTSP_E_UNSUPPORTED:
		/* Version Not supported */
	case RTSP_E_FAILURE:
	default:
		/* Must Be Request-Line */
		break;
	}
	return (e_ret_val);
}
static inline rtsp_error_t rtsp_parse_request_line(rtsp_start_line_t *p_start_line, const char *rtsp_msg_buffer, int32_t rtsp_msg_len, const char **endptr){

	const char *parse_string = rtsp_msg_buffer;
	const char *end = rtsp_msg_buffer + rtsp_msg_len;
	const char *temp = NULL;
	rtsp_error_t e_ret_val = RTSP_E_FAILURE;

	if(!p_start_line || !rtsp_msg_buffer || rtsp_msg_len <= 0){
		return (RTSP_E_INVALID_ARG);
	}
	/* R[6.1]
	 * Request-Line = Method SP Request-URI SP RTSP-Version CRLF
	 * Allowing multiple SP since RFC Text H[5.1] suggests
	 */


	e_ret_val = rtsp_get_method(&p_start_line->request.method, parse_string, rtsp_msg_len, &parse_string);
	
	if(e_ret_val != RTSP_E_SUCCESS ){
		return (e_ret_val);
	}

	/* Found valid Method Hence it is request line */ 
	p_start_line->msg_type = RTSP_MSG_REQUEST;

    /* SP */
	temp = skip_SP(parse_string, end);
	if((NULL == temp) || (temp==parse_string)){
		/* No spaces */
		e_ret_val = RTSP_E_FAILURE;
		return(e_ret_val);
	}else if(temp==end){
		/* Only spaces till end */
		e_ret_val = RTSP_E_INCOMPLETE;
		return(e_ret_val);
	}
	parse_string = temp;

	/* Request-URI  */
	e_ret_val = rtsp_get_url(&p_start_line->request.url ,parse_string, (rtsp_msg_len - (parse_string - rtsp_msg_buffer)), &parse_string);
	if(e_ret_val != RTSP_E_SUCCESS){
		ERR_LOG("Failed to parse URI");
		return (e_ret_val);
	}

	/* SP */
	temp = skip_SP(parse_string, end);
	if((NULL == temp) || (temp==parse_string)){
		/* No spaces */
		e_ret_val = RTSP_E_FAILURE;
		return(e_ret_val);
	}else if(temp==end){
		/* Only spaces till end */
		e_ret_val = RTSP_E_INCOMPLETE;
		return(e_ret_val);
	}
	parse_string = temp;

	/* RTSP-Version */
	e_ret_val = rtsp_get_version(&p_start_line->version, parse_string, (rtsp_msg_len - (parse_string - rtsp_msg_buffer)) , &parse_string);
	
	if(e_ret_val != RTSP_E_SUCCESS){
		return (e_ret_val);
	}

	/* CRLF */
	if((parse_string+2)  < end){
		if((*parse_string++ == RTSP_CR) && (*parse_string++ == RTSP_LF)){
			e_ret_val = RTSP_E_SUCCESS;
		} else {
			e_ret_val = RTSP_E_FAILURE;
		}
	} else {
		e_ret_val = RTSP_E_INCOMPLETE;
	}

	if(endptr)
		*endptr = parse_string;
	return (e_ret_val);
}
예제 #3
0
static void rtsp_server_handle(struct rtsp_server_request_t *req, void* parser)
{
	int major, minor;
	const char* uri;
	const char* method;

	req->parser = parser;
	rtsp_get_version(parser, &major, &minor);
	if(1 != major && 0 != minor)
	{
		//505 RTSP Version Not Supported
		rtsp_server_reply(req, 505);
		return;
	}

	if(0 != rtsp_get_header_by_name2(parser, "CSeq", (int*)&req->cseq))
	{
		// 400 Bad Request
		rtsp_server_reply(req, 400);
		return;
	}

	uri = rtsp_get_request_uri(parser);
	method = rtsp_get_request_method(parser);

	switch(*method)
	{
	case 'o':
	case 'O':
		if(0 == stricmp("OPTIONS", method))
		{
			rtsp_server_options(req, parser, uri);
			return;
		}
		break;

	case 'd':
	case 'D':
		if(0 == stricmp("DESCRIBE", method))
		{
			rtsp_server_describe(req, parser, uri);
			return;
		}
		break;

	case 's':
	case 'S':
		if(0 == stricmp("SETUP", method))
		{
			rtsp_server_setup(req, parser, uri);
			return;
		}
		break;

	case 'p':
	case 'P':
		if(0 == stricmp("PLAY", method))
		{
			rtsp_server_play(req, parser, uri);
			return;
		}
		else if(0 == stricmp("PAUSE", method))
		{
			rtsp_server_pause(req, parser, uri);
			return;
		}
		break;

	case 't':
	case 'T':
		if(0 == stricmp("TEARDOWN", method))
		{
			rtsp_server_teardown(req, parser, uri);
			return;
		}
		break;
	}

	// 501 Not implemented
	rtsp_server_reply(req, 501);
}