/*
 * OpenMRCP - Open Source Media Resource Control Protocol Stack
 * Copyright (C) 2007, Cepstral LLC
 *
 * Version: MPL 1.1
 *
 * 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.
 *
 * Author(s):
 * Arsen Chaloyan <achaloyan@yahoo.com>
 *
 * Contributor(s):
 *
 */

#include "rtsp_message.h"
#include "apt_string_table.h"

/** Parse RTSP message-body */
static apt_bool_t rtsp_body_parse(rtsp_message_t *message, apt_text_stream_t *text_stream)
{
	if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE) {
		if(message->header.content_length) {
			size_t length = message->header.content_length;
			message->body = apr_palloc(message->pool,length+1);
			memcpy(message->body,text_stream->pos,length);
			message->body[length] = '\0';
			text_stream->pos += length;
		}
	}
	return TRUE;
}

/* Generate RTSP message-body */
static apt_bool_t rtsp_body_generate(rtsp_message_t *message, apt_text_stream_t *text_stream)
{
	if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE) {
		size_t length;
		if(!message->body) {
			return FALSE;
		}
		length = message->header.content_length;
		memcpy(text_stream->pos,message->body,length);
		text_stream->pos += length;
	}
	return TRUE;
}

/** Create RTSP request message */
rtsp_message_t* rtsp_request_create(apr_pool_t *pool)
{
	rtsp_message_t *request = rtsp_message_create(RTSP_MESSAGE_TYPE_REQUEST,pool);
	request->start_line.common.request_line.version = RTSP_VERSION_1;
	return request;
}

/** Create RTSP response message */
rtsp_message_t* rtsp_response_create(rtsp_message_t *request, rtsp_status_code_t status_code, const char *reason, apr_pool_t *pool)
{
	rtsp_message_t *response = rtsp_message_create(RTSP_MESSAGE_TYPE_RESPONSE,request->pool);
	response->start_line.common.status_line.version = request->start_line.common.request_line.version;
	response->start_line.common.status_line.status_code = status_code;
	response->start_line.common.status_line.reason = reason;

	if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_CSEQ) == TRUE) {
		response->header.cseq = request->header.cseq;
		rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CSEQ);
	}

	return response;
}

/** Parse RTSP message */
apt_bool_t rtsp_message_parse(rtsp_message_t *message, apt_text_stream_t *text_stream)
{
	if(rtsp_start_line_parse(&message->start_line,text_stream,message->pool) == FALSE) {
		return FALSE;
	}

	if(rtsp_header_parse(&message->header,text_stream,message->pool) == FALSE) {
		return FALSE;
	}

	rtsp_body_parse(message,text_stream);

	return TRUE;
}

/** Generate RTSP message */
apt_bool_t rtsp_message_generate(rtsp_message_t *message, apt_text_stream_t *text_stream)
{
	if(rtsp_start_line_generate(&message->start_line,text_stream) == FALSE) {
		return FALSE;
	}

	if(rtsp_header_generate(&message->header,text_stream) == FALSE) {
		return FALSE;
	}

	rtsp_body_generate(message,text_stream);
	
	text_stream->size = text_stream->pos - text_stream->buffer;
	return TRUE;
}
