/* Load demo verification result */
static apt_bool_t demo_verifier_result_load(demo_verifier_channel_t *verifier_channel, mrcp_message_t *message)
{
	FILE *file;
	mrcp_engine_channel_t *channel = verifier_channel->channel;
	const apt_dir_layout_t *dir_layout = channel->engine->dir_layout;
	char *file_path = apt_datadir_filepath_get(dir_layout,"result-verification.xml",message->pool);
	if(!file_path) {
		return FALSE;
	}
	
	/* read the demo result from file */
	file = fopen(file_path,"r");
	if(file) {
		mrcp_generic_header_t *generic_header;
		char text[1024];
		apr_size_t size;
		size = fread(text,1,sizeof(text),file);
		apt_string_assign_n(&message->body,text,size,message->pool);
		fclose(file);

		/* get/allocate generic header */
		generic_header = mrcp_generic_header_prepare(message);
		if(generic_header) {
			/* set content types */
			apt_string_assign(&generic_header->content_type,"application/nlsml+xml",message->pool);
			mrcp_generic_header_property_add(message,GENERIC_HEADER_CONTENT_TYPE);
		}
	}
	return TRUE;
}
Example #2
0
mrcp_message_t* RecogSession::CreateDefineGrammarRequest(mrcp_channel_t* pMrcpChannel)
{
	mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_DEFINE_GRAMMAR);
	if(!pMrcpMessage)
		return NULL;

	const RecogScenario* pScenario = GetScenario();

	mrcp_generic_header_t* pGenericHeader;
	/* get/allocate generic header */
	pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pMrcpMessage);
	if(pGenericHeader) 
	{
		/* set generic header fields */
		if(pScenario->GetContentType())
		{
			apt_string_assign(&pGenericHeader->content_type,pScenario->GetContentType(),pMrcpMessage->pool);
			mrcp_generic_header_property_add(pMrcpMessage,GENERIC_HEADER_CONTENT_TYPE);
		}
		apt_string_assign(&pGenericHeader->content_id,m_ContentId,pMrcpMessage->pool);
		mrcp_generic_header_property_add(pMrcpMessage,GENERIC_HEADER_CONTENT_ID);
	}

	/* set message body */
	if(pScenario->GetContent())
		apt_string_assign_n(&pMrcpMessage->body,pScenario->GetContent(),pScenario->GetContentLength(),pMrcpMessage->pool);
	return pMrcpMessage;
}
/** Generate MRCP speech-length value */
static apt_bool_t mrcp_speech_length_generate(mrcp_speech_length_value_t *speech_length, apt_str_t *str, apr_pool_t *pool)
{
	if(speech_length->type == SPEECH_LENGTH_TYPE_TEXT) {
		apt_str_t *tag = &speech_length->value.tag;
		if(tag->length) {
			apt_string_copy(str,tag,pool);
		}
	}
	else {
		char buf[256];
		apt_text_stream_t stream;
		apt_text_stream_init(&stream,buf,sizeof(buf));
		if(speech_length->type == SPEECH_LENGTH_TYPE_NUMERIC_POSITIVE) {
			*stream.pos++ = '+';
		}
		else {
			*stream.pos++ = '-';
		}
		apt_text_size_value_insert(&stream,speech_length->value.numeric.length);
		*stream.pos++ = APT_TOKEN_SP;
		apt_string_table_value_generate(speech_unit_string_table,SPEECH_UNIT_COUNT,speech_length->value.numeric.unit,&stream);

		apt_string_assign_n(str,stream.text.buf, stream.pos - stream.text.buf, pool);
	}
	return TRUE;
}
Example #4
0
mrcp_message_t* RecogSession::CreateRecognizeRequest(mrcp_channel_t* pMrcpChannel)
{
	mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_RECOGNIZE);
	if(!pMrcpMessage)
		return NULL;

	const RecogScenario* pScenario = GetScenario();

	mrcp_generic_header_t* pGenericHeader;
	mrcp_recog_header_t* pRecogHeader;

	/* get/allocate generic header */
	pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pMrcpMessage);
	if(pGenericHeader)
	{
		/* set generic header fields */
		if(pScenario->IsDefineGrammarEnabled())
		{
			apt_string_assign(&pGenericHeader->content_type,"text/uri-list",pMrcpMessage->pool);
			/* set message body */
			const char* pContent = apr_pstrcat(pMrcpMessage->pool,"session:",m_ContentId,NULL);
			apt_string_set(&pMrcpMessage->body,pContent);
		}
		else
		{
			apt_string_assign(&pGenericHeader->content_type,pScenario->GetContentType(),pMrcpMessage->pool);
			/* set content-id */
			apt_string_assign(&pGenericHeader->content_id,m_ContentId,pMrcpMessage->pool);
			mrcp_generic_header_property_add(pMrcpMessage,GENERIC_HEADER_CONTENT_ID);
			/* set message body */
			if(pScenario->GetContent())
				apt_string_assign_n(&pMrcpMessage->body,pScenario->GetContent(),pScenario->GetContentLength(),pMrcpMessage->pool);
		}
		mrcp_generic_header_property_add(pMrcpMessage,GENERIC_HEADER_CONTENT_TYPE);
	}
	/* get/allocate recognizer header */
	pRecogHeader = (mrcp_recog_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
	if(pRecogHeader)
	{
		/* set recognizer header fields */
		if(pMrcpMessage->start_line.version == MRCP_VERSION_2)
		{
			pRecogHeader->cancel_if_queue = FALSE;
			mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_CANCEL_IF_QUEUE);
		}
		pRecogHeader->no_input_timeout = 5000;
		mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_NO_INPUT_TIMEOUT);
		pRecogHeader->recognition_timeout = 10000;
		mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_RECOGNITION_TIMEOUT);
		pRecogHeader->start_input_timers = TRUE;
		mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_START_INPUT_TIMERS);
		pRecogHeader->confidence_threshold = 0.87f;
		mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD);
		pRecogHeader->save_waveform = TRUE;
		mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_SAVE_WAVEFORM);
	}
	return pMrcpMessage;
}
/** Generate array of name-value pairs */
APT_DECLARE(apt_bool_t) apt_pair_array_generate(const apt_pair_arr_t *arr, apt_str_t *str, apr_pool_t *pool)
{
	char buf[512];
	apt_text_stream_t stream;
	apt_text_stream_init(&stream,buf,sizeof(buf));
	if(apt_text_pair_array_insert(&stream,arr) == FALSE) {
		return FALSE;
	}
	apt_string_assign_n(str, stream.text.buf, stream.pos - stream.text.buf, pool);
	return TRUE;
}
Example #6
0
static void demo_message_body_set(mrcp_message_t *mrcp_message, const apt_dir_layout_t *dir_layout, const char *file_name)
{
	char *file_path = apt_datadir_filepath_get(dir_layout,file_name,mrcp_message->pool);
	if(file_path) {
		FILE *file = fopen(file_path,"r");
		if(file) {
			char text[1024];
			apr_size_t size;
			size = fread(text,1,sizeof(text),file);
			apt_string_assign_n(&mrcp_message->body,text,size,mrcp_message->pool);
			fclose(file);
		}
	}
}
/** Generate mrcp request-id list */
static apt_bool_t mrcp_request_id_list_generate(mrcp_request_id_list_t *request_id_list, apt_str_t *str, apr_pool_t *pool)
{
	apr_size_t i;
	char buf[256];
	apt_text_stream_t stream;
	apt_text_stream_init(&stream,buf,sizeof(buf));
	for(i=0; i<request_id_list->count; i++) {
		mrcp_request_id_generate(request_id_list->ids[i],&stream);
		if(i < request_id_list->count-1) {
			*stream.pos++ = ',';
		}
	}

	apt_string_assign_n(str,stream.text.buf, stream.pos - stream.text.buf, pool);
	return TRUE;
}
/** Generate completion-cause */
APT_DECLARE(apt_bool_t) apt_completion_cause_generate(const apt_str_table_item_t table[], apr_size_t size, apr_size_t cause, apt_str_t *str, apr_pool_t *pool)
{
	char buf[256];
	int length;
	const apt_str_t *name = apt_string_table_str_get(table,size,cause);
	if(!name) {
		return FALSE;
	}
	length = sprintf(buf,"%03"APR_SIZE_T_FMT" ",cause);
	if(length <= 0) {
		return FALSE;
	}

	memcpy(buf+length,name->buf,name->length);
	apt_string_assign_n(str,buf,name->length + length,pool);
	return TRUE;
}
Example #9
0
/** Generate RTSP resource discovery response */
MRCP_DECLARE(rtsp_message_t*) rtsp_resource_discovery_response_generate(
											const rtsp_message_t *request, 
											const char *ip,
											const char *origin,
											apr_pool_t *pool)
{
	rtsp_message_t *response = rtsp_response_create(request,RTSP_STATUS_CODE_OK,RTSP_REASON_PHRASE_OK,pool);
	if(response) {
		apr_size_t offset = 0;
		char buffer[2048];
		apr_size_t size = sizeof(buffer);
		
		if(!ip) {
			ip = "0.0.0.0";
		}
		if(!origin) {
			origin = "-";
		}
		
		buffer[0] = '\0';
		offset += snprintf(buffer+offset,size-offset,
			"v=0\r\n"
			"o=%s 0 0 IN IP4 %s\r\n"
			"s=-\r\n"
			"c=IN IP4 %s\r\n"
			"t=0 0\r\n"
			"m=audio 0 RTP/AVP 0 8 96 101\r\n"
			"a=rtpmap:0 PCMU/8000\r\n"
			"a=rtpmap:8 PCMA/8000\r\n"
			"a=rtpmap:96 L16/8000\r\n"
			"a=rtpmap:101 telephone-event/8000\r\n",
			origin,
			ip,
			ip);
		
		if(offset) {
			apt_string_assign_n(&response->body,buffer,offset,pool);
			response->header.content_type = RTSP_CONTENT_TYPE_SDP;
			rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE);
			response->header.content_length = offset;
			rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH);
		}
	}

	return response;
}
Example #10
0
/** Create DEFINE-GRAMMAR request */
static mrcp_message_t* define_grammar_message_create(asr_session_t *asr_session, const char *grammar_file)
{
	/* create MRCP message */
	mrcp_message_t *mrcp_message = mrcp_application_message_create(
						asr_session->mrcp_session,
						asr_session->mrcp_channel,
						RECOGNIZER_DEFINE_GRAMMAR);
	if(mrcp_message) {
		mrcp_generic_header_t *generic_header;

		/* set message body */
		const apt_dir_layout_t *dir_layout = mrcp_application_dir_layout_get(asr_session->engine->mrcp_app);
		apr_pool_t *pool = mrcp_application_session_pool_get(asr_session->mrcp_session);
		char *grammar_file_path = apt_datadir_filepath_get(dir_layout,grammar_file,pool);
		if(grammar_file_path) {
			char text[1024];
			apr_size_t size;
			FILE *grammar = fopen(grammar_file_path,"r");
			if(!grammar) {
				apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Open [%s]",grammar_file_path);
				return NULL;
			}

			size = fread(text,1,sizeof(text),grammar);
			apt_string_assign_n(&mrcp_message->body,text,size,mrcp_message->pool);
			fclose(grammar);
		}

		/* get/allocate generic header */
		generic_header = mrcp_generic_header_prepare(mrcp_message);
		if(generic_header) {
			/* set generic header fields */
			if(mrcp_message->start_line.version == MRCP_VERSION_2) {
				apt_string_assign(&generic_header->content_type,"application/srgs+xml",mrcp_message->pool);
			}
			else {
				apt_string_assign(&generic_header->content_type,"application/grammar+xml",mrcp_message->pool);
			}
			mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_TYPE);
			apt_string_assign(&generic_header->content_id,"demo-grammar",mrcp_message->pool);
			mrcp_generic_header_property_add(mrcp_message,GENERIC_HEADER_CONTENT_ID);
		}
	}
	return mrcp_message;
}
Example #11
0
/** Generate RTSP response by MRCP descriptor */
MRCP_DECLARE(rtsp_message_t*) rtsp_response_generate_by_mrcp_descriptor(const rtsp_message_t *request, const mrcp_session_descriptor_t *descriptor, const apr_table_t *resource_map, apr_pool_t *pool)
{
	rtsp_message_t *response = NULL;

	switch(descriptor->status) {
		case MRCP_SESSION_STATUS_OK:
			response = rtsp_response_create(request,RTSP_STATUS_CODE_OK,RTSP_REASON_PHRASE_OK,pool);
			break;
		case MRCP_SESSION_STATUS_NO_SUCH_RESOURCE:
			response = rtsp_response_create(request,RTSP_STATUS_CODE_NOT_FOUND,RTSP_REASON_PHRASE_NOT_FOUND,pool);
			break;
		case MRCP_SESSION_STATUS_UNACCEPTABLE_RESOURCE:
		case MRCP_SESSION_STATUS_UNAVAILABLE_RESOURCE:
			response = rtsp_response_create(request,RTSP_STATUS_CODE_NOT_ACCEPTABLE,RTSP_REASON_PHRASE_NOT_ACCEPTABLE,pool);
			break;
		case MRCP_SESSION_STATUS_ERROR:
			response = rtsp_response_create(request,RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR,RTSP_REASON_PHRASE_INTERNAL_SERVER_ERROR,pool);
			break;
	}

	if(!response) {
		return NULL;
	}

	if(descriptor->status == MRCP_SESSION_STATUS_OK) {
		apr_size_t i;
		apr_size_t count;
		apr_size_t audio_index = 0;
		mpf_rtp_media_descriptor_t *audio_media;
		apr_size_t video_index = 0;
		mpf_rtp_media_descriptor_t *video_media;
		apr_size_t offset = 0;
		char buffer[2048];
		apr_size_t size = sizeof(buffer);
		const char *ip = descriptor->ext_ip.buf ? descriptor->ext_ip.buf : (descriptor->ip.buf ? descriptor->ip.buf : "0.0.0.0");

		buffer[0] = '\0';
		offset += snprintf(buffer+offset,size-offset,
				"v=0\r\n"
				"o=%s 0 0 IN IP4 %s\r\n"
				"s=-\r\n"
				"c=IN IP4 %s\r\n"
				"t=0 0\r\n",
				descriptor->origin.buf ? descriptor->origin.buf : "-",
				ip,
				ip);
		count = mrcp_session_media_count_get(descriptor);
		for(i=0; i<count; i++) {
			audio_media = mrcp_session_audio_media_get(descriptor,audio_index);
			if(audio_media && audio_media->id == i) {
				/* generate audio media */
				rtsp_transport_t *transport;
				audio_index++;
				offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,audio_media);
				transport = &response->header.transport;
				transport->server_port_range.min = audio_media->port;
				transport->server_port_range.max = audio_media->port+1;
				transport->client_port_range = request->header.transport.client_port_range;
				continue;
			}
			video_media = mrcp_session_video_media_get(descriptor,video_index);
			if(video_media && video_media->id == i) {
				/* generate video media */
				video_index++;
				offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,video_media);
				continue;
			}
		}

		/* ok */
		response->header.transport.protocol = RTSP_TRANSPORT_RTP;
		response->header.transport.profile = RTSP_PROFILE_AVP;
		response->header.transport.delivery = RTSP_DELIVERY_UNICAST;
		rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_TRANSPORT);

		if(offset) {
			apt_string_assign_n(&response->body,buffer,offset,pool);
			response->header.content_type = RTSP_CONTENT_TYPE_SDP;
			rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE);
			response->header.content_length = offset;
			rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH);
		}
	}
	return response;
}
Example #12
0
/** Generate RTSP request by MRCP descriptor */
MRCP_DECLARE(rtsp_message_t*) rtsp_request_generate_by_mrcp_descriptor(const mrcp_session_descriptor_t *descriptor, const apr_table_t *resource_map, apr_pool_t *pool)
{
	apr_size_t i;
	apr_size_t count;
	apr_size_t audio_index = 0;
	mpf_rtp_media_descriptor_t *audio_media;
	apr_size_t video_index = 0;
	mpf_rtp_media_descriptor_t *video_media;
	apr_size_t offset = 0;
	char buffer[2048];
	apr_size_t size = sizeof(buffer);
	rtsp_message_t *request;
	const char *ip = descriptor->ext_ip.buf ? descriptor->ext_ip.buf : (descriptor->ip.buf ? descriptor->ip.buf : "0.0.0.0");

	request = rtsp_request_create(pool);
	request->start_line.common.request_line.resource_name = rtsp_name_get_by_mrcp_name(
		resource_map,
		descriptor->resource_name.buf);
	if(descriptor->resource_state != TRUE) {
		request->start_line.common.request_line.method_id = RTSP_METHOD_TEARDOWN;
		return request;
	}

	request->start_line.common.request_line.method_id = RTSP_METHOD_SETUP;

	buffer[0] = '\0';
	offset += snprintf(buffer+offset,size-offset,
			"v=0\r\n"
			"o=%s 0 0 IN IP4 %s\r\n"
			"s=-\r\n"
			"c=IN IP4 %s\r\n"
			"t=0 0\r\n",
			descriptor->origin.buf ? descriptor->origin.buf : "-",
			ip,
			ip);
	count = mrcp_session_media_count_get(descriptor);
	for(i=0; i<count; i++) {
		audio_media = mrcp_session_audio_media_get(descriptor,audio_index);
		if(audio_media && audio_media->id == i) {
			/* generate audio media */
			audio_index++;
			offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,audio_media);
			request->header.transport.client_port_range.min = audio_media->port;
			request->header.transport.client_port_range.max = audio_media->port+1;
			continue;
		}
		video_media = mrcp_session_video_media_get(descriptor,video_index);
		if(video_media && video_media->id == i) {
			/* generate video media */
			video_index++;
			offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,video_media);
			continue;
		}
	}

	request->header.transport.protocol = RTSP_TRANSPORT_RTP;
	request->header.transport.profile = RTSP_PROFILE_AVP;
	request->header.transport.delivery = RTSP_DELIVERY_UNICAST;
	rtsp_header_property_add(&request->header.property_set,RTSP_HEADER_FIELD_TRANSPORT);

	if(offset) {
		apt_string_assign_n(&request->body,buffer,offset,pool);
		request->header.content_type = RTSP_CONTENT_TYPE_SDP;
		rtsp_header_property_add(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE);
		request->header.content_length = offset;
		rtsp_header_property_add(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH);
	}
	return request;
}
/** Get the next content part */
APT_DECLARE(apt_bool_t) apt_multipart_content_get(apt_multipart_content_t *multipart_content, apt_content_part_t *content_part, apt_bool_t *is_final)
{
	apt_str_t boundary;
	apt_header_field_t *header_field;
	apt_text_stream_t *stream = &multipart_content->stream;

	if(!content_part || !is_final) {
		return FALSE;
	}
	*is_final = FALSE;
	apt_content_part_reset(content_part);

	/* skip preamble */
	apt_text_skip_to_char(stream,'-');
	if(apt_text_is_eos(stream) == TRUE) {
		return FALSE;
	}

	/* skip initial hyphens */
	apt_text_chars_skip(stream,'-');
	if(apt_text_is_eos(stream) == TRUE) {
		return FALSE;
	}

	/* read line and the boundary */
	if(apt_text_line_read(stream,&boundary) == FALSE) {
		return FALSE;
	}

	/* remove optional trailing spaces */
	while(boundary.length && boundary.buf[boundary.length-1] == APT_TOKEN_SP) boundary.length--;

	/* check whether this is the final boundary */
	if(boundary.length >= 2) {
		if(boundary.buf[boundary.length-1] == '-' && boundary.buf[boundary.length-2] == '-') {
			/* final boundary */
			boundary.length -= 2;
			*is_final = TRUE;
		}
	}

	/* compare boundaries */
	if(apt_string_is_empty(&multipart_content->boundary) == TRUE) {
		/* no boundary was specified from user space, 
		learn boundary from the content */
		multipart_content->boundary = boundary;
	}
	else {
		if(apt_string_compare(&multipart_content->boundary,&boundary) == FALSE) {
			/* invalid boundary */
			return FALSE;
		}
	}

	if(*is_final == TRUE) {
		/* final boundary => return TRUE, content remains empty */
		return TRUE;
	}

	/* read header fields */
	if(apt_header_section_parse(&content_part->header,stream,multipart_content->pool) == FALSE) {
		return FALSE;
	}
	
	for(header_field = APR_RING_FIRST(&content_part->header.ring);
			header_field != APR_RING_SENTINEL(&content_part->header.ring, apt_header_field_t, link);
				header_field = APR_RING_NEXT(header_field, link)) {
		if(strncmp(header_field->name.buf,CONTENT_LENGTH_HEADER,header_field->name.length) == 0) {
			content_part->length = &header_field->value;
		}
		else if(strncmp(header_field->name.buf,CONTENT_TYPE_HEADER,header_field->name.length) == 0) {
			content_part->type = &header_field->value;
		}
		else if(strncmp(header_field->name.buf,CONTENT_ID_HEADER,header_field->name.length) == 0) {
			content_part->id = &header_field->value;
		}
	}

	if(content_part->length && apt_string_is_empty(content_part->length) == FALSE) {
		apr_size_t length = atoi(content_part->length->buf);
		if(length + stream->pos > stream->end) {
			return FALSE;
		}

		/* read content */
		apt_string_assign_n(&content_part->body,stream->pos,length,multipart_content->pool);
		stream->pos += length;
	}

	return TRUE;
}
Example #14
0
/** Generate RTSP response by MRCP descriptor */
MRCP_DECLARE(rtsp_message_t*) rtsp_response_generate_by_mrcp_descriptor(const rtsp_message_t *request, const mrcp_session_descriptor_t *descriptor, apr_pool_t *pool)
{
	apr_size_t i;
	apr_size_t count;
	apr_size_t audio_index = 0;
	mpf_rtp_media_descriptor_t *audio_media;
	apr_size_t video_index = 0;
	mpf_rtp_media_descriptor_t *video_media;
	apr_size_t offset = 0;
	char buffer[2048];
	apr_size_t size = sizeof(buffer);
	rtsp_message_t *response;

	if(descriptor->resource_state != TRUE) {
		response = rtsp_response_create(request,RTSP_STATUS_CODE_NOT_FOUND,RTSP_REASON_PHRASE_NOT_FOUND,pool);
		return response;
	}

	response = rtsp_response_create(request,RTSP_STATUS_CODE_OK,RTSP_REASON_PHRASE_OK,pool);
	if(!response) {
		return NULL;
	}

	buffer[0] = '\0';
	offset += snprintf(buffer+offset,size-offset,
			"v=0\r\n"
			"o=%s 0 0 IN IP4 %s\r\n"
			"s=-\r\n"
			"c=IN IP4 %s\r\n"
			"t=0 0\r\n",
			descriptor->origin.buf ? descriptor->origin.buf : "-",
			descriptor->ip.buf ? descriptor->ip.buf : "0",
			descriptor->ip.buf ? descriptor->ip.buf : "0");
	count = mrcp_session_media_count_get(descriptor);
	for(i=0; i<count; i++) {
		audio_media = mrcp_session_audio_media_get(descriptor,audio_index);
		if(audio_media && audio_media->base.id == i) {
			/* generate audio media */
			audio_index++;
			offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,audio_media);
			continue;
		}
		video_media = mrcp_session_video_media_get(descriptor,video_index);
		if(video_media && video_media->base.id == i) {
			/* generate video media */
			video_index++;
			offset += sdp_rtp_media_generate(buffer+offset,size-offset,descriptor,video_media);
			continue;
		}
	}

	/* ok */
	response->header.transport.profile = RTSP_PROFILE_RTP_AVP;
	response->header.transport.delivery = RTSP_DELIVERY_UNICAST;
	rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_TRANSPORT);

	if(offset) {
		apt_string_assign_n(&response->body,buffer,offset,pool);
		response->header.content_type = RTSP_CONTENT_TYPE_SDP;
		rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE);
		response->header.content_length = offset;
		rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH);
	}
	return response;
}