static apt_bool_t mrcp_unirtsp_message_handle(rtsp_server_t *rtsp_server, rtsp_server_session_t *rtsp_session, rtsp_message_t *rtsp_message)
{
	apt_bool_t status = FALSE;
	mrcp_unirtsp_agent_t *agent = rtsp_server_object_get(rtsp_server);
	mrcp_unirtsp_session_t *session	= rtsp_server_session_object_get(rtsp_session);
	if(!session) {
		return FALSE;
	}

	switch(rtsp_message->start_line.common.request_line.method_id) {
		case RTSP_METHOD_SETUP:
		case RTSP_METHOD_TEARDOWN:
		{
			mrcp_session_descriptor_t *descriptor;
			descriptor = mrcp_descriptor_generate_by_rtsp_request(rtsp_message,agent->config->resource_map,
				session->mrcp_session->pool,session->home);
			status = mrcp_session_offer(session->mrcp_session,descriptor);
			break;
		}
		case RTSP_METHOD_ANNOUNCE:
		{
			mrcp_unirtsp_agent_t *agent = rtsp_server_object_get(rtsp_server);
			status = mrcp_unirtsp_session_announce(agent,session,rtsp_message);
			break;
		}
		default:
			break;
	}

	return status;
}
static apt_bool_t mrcp_unirtsp_message_handle(rtsp_server_t *rtsp_server, rtsp_server_session_t *rtsp_session, rtsp_message_t *rtsp_message)
{
	apt_bool_t status = FALSE;
	mrcp_unirtsp_agent_t *agent = rtsp_server_object_get(rtsp_server);
	mrcp_unirtsp_session_t *session	= rtsp_server_session_object_get(rtsp_session);
	if(!session) {
		return FALSE;
	}

	switch(rtsp_message->start_line.common.request_line.method_id) {
		case RTSP_METHOD_SETUP:
		case RTSP_METHOD_TEARDOWN:
		{
			const char *force_destination_ip = NULL;
			mrcp_session_descriptor_t *descriptor;

			if(agent->config->force_destination == TRUE) {
				force_destination_ip = rtsp_server_session_destination_get(rtsp_session);
			}
			descriptor = mrcp_descriptor_generate_by_rtsp_request(
							rtsp_message,
							force_destination_ip,
							agent->config->resource_map,
							session->mrcp_session->pool,
							session->home);
			if(!descriptor) {
				rtsp_message_t *response = rtsp_response_create(rtsp_message,
										RTSP_STATUS_CODE_BAD_REQUEST,
										RTSP_REASON_PHRASE_BAD_REQUEST,
										rtsp_message->pool);
				status = rtsp_server_session_respond(rtsp_server,session->rtsp_session,response);
				break;
			}
			status = mrcp_session_offer(session->mrcp_session,descriptor);
			break;
		}
		case RTSP_METHOD_ANNOUNCE:
		{
			status = mrcp_unirtsp_session_announce(agent,session,rtsp_message);
			break;
		}
		case RTSP_METHOD_DESCRIBE:
		{
			rtsp_message_t *response = rtsp_resource_discovery_response_generate(
						rtsp_message,
						agent->config->local_ip,
						agent->config->origin,
						session->mrcp_session->pool);
			status = rtsp_server_session_respond(rtsp_server,session->rtsp_session,response);
			break;
		}
		default:
			break;
	}

	return status;
}
static apt_bool_t mrcp_client_session_offer_send(mrcp_client_session_t *session)
{
	mrcp_session_descriptor_t *descriptor = session->offer;
	apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Send Offer <%s> [c:%d a:%d v:%d]",
		mrcp_session_str(session),
		descriptor->control_media_arr->nelts,
		descriptor->audio_media_arr->nelts,
		descriptor->video_media_arr->nelts);
	return mrcp_session_offer(&session->base,descriptor);
}
static apt_bool_t mrcp_client_session_offer_send(mrcp_client_session_t *session)
{
	mrcp_session_descriptor_t *descriptor = session->offer;
	apt_obj_log(APT_LOG_MARK,APT_PRIO_INFO,session->base.log_obj,"Send Offer "APT_NAMESID_FMT" [c:%d a:%d v:%d] to %s:%hu",
		MRCP_SESSION_NAMESID(session),
		descriptor->control_media_arr->nelts,
		descriptor->audio_media_arr->nelts,
		descriptor->video_media_arr->nelts,
		session->profile->signaling_settings->server_ip,
		session->profile->signaling_settings->server_port);
	return mrcp_session_offer(&session->base,descriptor);
}
static void mrcp_sofia_on_call_receive(mrcp_sofia_agent_t   *sofia_agent,
									   nua_handle_t         *nh,
									   mrcp_sofia_session_t *sofia_session,
									   sip_t const          *sip,
									   tagi_t                tags[])
{
	int offer_recv = 0, answer_recv = 0, offer_sent = 0, answer_sent = 0;
	const char *local_sdp_str = NULL, *remote_sdp_str = NULL;
	mrcp_session_descriptor_t *descriptor = NULL;

	tl_gets(tags, 
			NUTAG_OFFER_RECV_REF(offer_recv),
			NUTAG_ANSWER_RECV_REF(answer_recv),
			NUTAG_OFFER_SENT_REF(offer_sent),
			NUTAG_ANSWER_SENT_REF(answer_sent),
			SOATAG_LOCAL_SDP_STR_REF(local_sdp_str),
			SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str),
			TAG_END());
	
	if(!sofia_session) {
		sofia_session = mrcp_sofia_session_create(sofia_agent,nh);
		if(!sofia_session) {
			nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
			return;
		}
	}

	if(remote_sdp_str) {
		sdp_parser_t *parser = NULL;
		sdp_session_t *sdp = NULL;
		apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remote SDP\n%s", remote_sdp_str);

		parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0);
		sdp = sdp_session(parser);		
		descriptor = mrcp_descriptor_generate_by_sdp_session(sdp,NULL,sofia_session->session->pool);
		sdp_parser_free(parser);
	}

	if(!descriptor) {
		nua_respond(nh, SIP_400_BAD_REQUEST, TAG_END());
		return;
	}

	mrcp_session_offer(sofia_session->session,descriptor);
}
static void mrcp_sofia_on_call_receive(mrcp_sofia_agent_t   *sofia_agent,
									   nua_handle_t         *nh,
									   mrcp_sofia_session_t *sofia_session,
									   sip_t const          *sip,
									   tagi_t                tags[])
{
	apt_bool_t status = FALSE;
	const char *remote_sdp_str = NULL;
	mrcp_session_descriptor_t *descriptor;

	if(!sofia_session) {
		sofia_session = mrcp_sofia_session_create(sofia_agent,nh);
		if(!sofia_session) {
			nua_respond(nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
			return;
		}
	}

	descriptor = mrcp_session_descriptor_create(sofia_session->session->pool);

	tl_gets(tags, 
			SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str),
			TAG_END());

	if(remote_sdp_str) {
		sdp_parser_t *parser = NULL;
		sdp_session_t *sdp = NULL;
		apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remote SDP "APT_NAMESID_FMT"\n%s",
			sofia_session->session->name,
			MRCP_SESSION_SID(sofia_session->session),
			remote_sdp_str);

		parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0);
		sdp = sdp_session(parser);
		status = mrcp_descriptor_generate_by_sdp_session(descriptor,sdp,NULL,sofia_session->session->pool);
		sdp_parser_free(parser);
	}

	if(status == FALSE) {
		nua_respond(nh, SIP_400_BAD_REQUEST, TAG_END());
		return;
	}

	mrcp_session_offer(sofia_session->session,descriptor);
}