예제 #1
0
/* Process incoming RTSP event (request) */
static apt_bool_t rtsp_client_session_event_process(rtsp_client_t *client, rtsp_client_connection_t *rtsp_connection, rtsp_message_t *message)
{
	rtsp_message_t *response = NULL;
	rtsp_client_session_t *session = NULL;
	if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) {
		/* find existing session */
		session = apr_hash_get(
					rtsp_connection->session_table,
					message->header.session_id.buf,
					message->header.session_id.length);
	}

	if(session) {
		response = rtsp_response_create(message,RTSP_STATUS_CODE_OK,RTSP_REASON_PHRASE_OK,message->pool);
		if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) {
			response->header.session_id = message->header.session_id;
			rtsp_header_property_add(&response->header.property_set,RTSP_HEADER_FIELD_SESSION_ID);
		}
		client->vtable->on_session_event(client,session,message);
	}
	else {
		response = rtsp_response_create(message,RTSP_STATUS_CODE_NOT_FOUND,RTSP_REASON_PHRASE_NOT_FOUND,message->pool);
	}

	return rtsp_client_message_send(client,rtsp_connection->base,response);
}
예제 #2
0
/** Generate MRCP descriptor by RTSP request */
MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_descriptor_generate_by_rtsp_request(
											const rtsp_message_t *request,
											const char *force_destination_ip,
											const apr_table_t *resource_map,
											apr_pool_t *pool,
											su_home_t *home)
{
	mrcp_session_descriptor_t *descriptor = NULL;
	const char *resource_name = mrcp_name_get_by_rtsp_name(
		resource_map,
		request->start_line.common.request_line.resource_name);
	if(!resource_name) {
		return NULL;
	}
	
	if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) {
		if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE &&
			rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE &&
			request->body.buf) {
			
			sdp_parser_t *parser;
			sdp_session_t *sdp;

			parser = sdp_parse(home,request->body.buf,request->body.length,0);
			sdp = sdp_session(parser);
			if(sdp) {
				descriptor = mrcp_session_descriptor_create(pool);
				mrcp_descriptor_generate_by_sdp_session(descriptor,sdp,force_destination_ip,pool);
			}
			else {
				apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse SDP Message");
			}
			sdp_parser_free(parser);
		}
		else {
			/* create default descriptor in case RTSP SETUP contains no SDP */
			mpf_rtp_media_descriptor_t *media;
			descriptor = mrcp_session_descriptor_create(pool);
			media = apr_palloc(pool,sizeof(mpf_rtp_media_descriptor_t));
			mpf_rtp_media_descriptor_init(media);
			media->state = MPF_MEDIA_ENABLED;
			media->id = mrcp_session_audio_media_add(descriptor,media);
			if(rtsp_header_property_check(&request->header.property_set,RTSP_HEADER_FIELD_TRANSPORT) == TRUE) {
				media->port = request->header.transport.client_port_range.min;
				media->ip = request->header.transport.destination;
			}
		}

		if(descriptor) {
			apt_string_assign(&descriptor->resource_name,resource_name,pool);
			descriptor->resource_state = TRUE;
		}
	}
	else if(request->start_line.common.request_line.method_id == RTSP_METHOD_TEARDOWN) {
		descriptor = mrcp_session_descriptor_create(pool);
		apt_string_assign(&descriptor->resource_name,resource_name,pool);
		descriptor->resource_state = FALSE;
	}
	return descriptor;
}
예제 #3
0
/** Generate MRCP descriptor by RTSP response */
MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_descriptor_generate_by_rtsp_response(
											const rtsp_message_t *request, 
											const rtsp_message_t *response, 
											const char *force_destination_ip,
											const apr_table_t *resource_map, 
											apr_pool_t *pool, 
											su_home_t *home)
{
	mrcp_session_descriptor_t *descriptor = NULL;
	const char *resource_name = mrcp_name_get_by_rtsp_name(
		resource_map,
		request->start_line.common.request_line.resource_name);
	if(!resource_name) {
		return NULL;
	}

	if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) {
		if(rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE &&
			rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE &&
			response->body.buf) {

			sdp_parser_t *parser;
			sdp_session_t *sdp;

			parser = sdp_parse(home,response->body.buf,response->body.length,0);
			sdp = sdp_session(parser);
			if(sdp) {
				descriptor = mrcp_session_descriptor_create(pool);
				mrcp_descriptor_generate_by_sdp_session(descriptor,sdp,force_destination_ip,pool);

				apt_string_assign(&descriptor->resource_name,resource_name,pool);
				descriptor->resource_state = TRUE;
				descriptor->response_code = response->start_line.common.status_line.status_code;
			}
			else {
				apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse SDP Message");
			}

			sdp_parser_free(parser);
		}
		else {
			descriptor = mrcp_session_descriptor_create(pool);
			apt_string_assign(&descriptor->resource_name,resource_name,pool);
			descriptor->resource_state = FALSE;
		}
	}
	else if(request->start_line.common.request_line.method_id == RTSP_METHOD_TEARDOWN) {
		descriptor = mrcp_session_descriptor_create(pool);
		apt_string_assign(&descriptor->resource_name,resource_name,pool);
		descriptor->resource_state = FALSE;
	}
	return descriptor;
}
static apt_bool_t mrcp_unirtsp_on_announce_response(mrcp_unirtsp_agent_t *agent, mrcp_unirtsp_session_t *session, rtsp_message_t *message, const char *resource_name)
{
	mrcp_message_t *mrcp_message = NULL;

	if(!session || !resource_name) {
		return FALSE;
	}
	
	if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE &&
		message->header.content_type == RTSP_CONTENT_TYPE_MRCP &&
		rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE &&
		message->header.content_length > 0) {

		apt_text_stream_t text_stream;
		mrcp_parser_t *parser;
		apt_str_t resource_name_str;

		text_stream.text = message->body;
		apt_text_stream_reset(&text_stream);
		apt_string_set(&resource_name_str,resource_name);

		parser = mrcp_parser_create(agent->sig_agent->resource_factory,session->mrcp_session->pool);
		mrcp_parser_resource_set(parser,&resource_name_str);
		if(mrcp_parser_run(parser,&text_stream,&mrcp_message) == APT_MESSAGE_STATUS_COMPLETE) {
			mrcp_message->channel_id.session_id = message->header.session_id;
		}
		else {
			/* error case */
			apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCPv1 Message");
		}
	}
	else {
		/* error case */
		apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Determine MRCPv1 Message Content");
	}

	if(!mrcp_message) {
		if(!session->mrcp_message) {
			return FALSE;
		}
		mrcp_message = mrcp_response_create(session->mrcp_message,session->mrcp_session->pool);
		mrcp_message->start_line.status_code = MRCP_STATUS_CODE_METHOD_FAILED;
	}

	if(session->mrcp_message && mrcp_message->start_line.request_id == session->mrcp_message->start_line.request_id) {
		session->mrcp_message = NULL;
	}
	mrcp_session_control_response(session->mrcp_session,mrcp_message);
	return TRUE;
}
예제 #5
0
/** Generate RTSP header */
RTSP_DECLARE(apt_bool_t) rtsp_header_generate(rtsp_header_t *header, apt_text_stream_t *text_stream)
{
    const apt_str_t *name;
    apr_size_t i;
    rtsp_header_property_t property_set;

    property_set = header->property_set;
    for(i=0; i<RTSP_HEADER_FIELD_COUNT && property_set != 0; i++) {
        if(rtsp_header_property_check(&property_set,i) == TRUE) {
            name = apt_string_table_str_get(rtsp_header_string_table,RTSP_HEADER_FIELD_COUNT,i);
            if(!name) {
                continue;
            }

            apt_text_header_name_generate(name,text_stream);
            rtsp_header_field_generate(header,i,text_stream);
            apt_text_eol_insert(text_stream);

            rtsp_header_property_remove(&property_set,i);
        }
    }

    apt_text_eol_insert(text_stream);
    return TRUE;
}
예제 #6
0
/* Process incoming RTSP request */
static apt_bool_t rtsp_server_session_request_process(rtsp_server_t *server, rtsp_server_connection_t *rtsp_connection, rtsp_message_t *message)
{
	rtsp_server_session_t *session = NULL;
	if(message->start_line.message_type != RTSP_MESSAGE_TYPE_REQUEST) {
		/* received response to ANNOUNCE request/event */
		return TRUE;
	}

	if(rtsp_header_property_check(&message->header,RTSP_HEADER_FIELD_SESSION_ID) != TRUE) {
		/* no session-id specified */
		session = rtsp_server_session_setup_process(server,rtsp_connection,message);
		if(session) {
			session->active_request = message;
			if(rtsp_server_session_message_handle(server,session,message) != TRUE) {
				rtsp_server_session_destroy(session);
			}
		}
		else {
			/* error case, failed to create a session */
			apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Create RTSP Session");
			return rtsp_server_error_respond(server,rtsp_connection,message,
									RTSP_STATUS_CODE_NOT_ACCEPTABLE,
									RTSP_REASON_PHRASE_NOT_ACCEPTABLE);
		}
		return TRUE;
	}

	/* existing session */
	session = apr_hash_get(
				rtsp_connection->session_table,
				message->header.session_id.buf,
				message->header.session_id.length);
	if(!session) {
		/* error case, no such session */
		apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"No Such RTSP Session " APT_SID_FMT,message->header.session_id.buf);
		return rtsp_server_error_respond(server,rtsp_connection,message,
								RTSP_STATUS_CODE_NOT_FOUND,
								RTSP_REASON_PHRASE_NOT_FOUND);
	}

	if(session->terminating == TRUE) {
		/* error case, session is being terminated */
		apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Not Acceptable Request " APT_SID_FMT,message->header.session_id.buf);
		return rtsp_server_error_respond(server,rtsp_connection,message,
								RTSP_STATUS_CODE_NOT_ACCEPTABLE,
								RTSP_REASON_PHRASE_NOT_ACCEPTABLE);
	}

	if(session->active_request) {
		apt_log(RTSP_LOG_MARK,APT_PRIO_DEBUG,"Push RTSP Request to Queue " APT_SID_FMT,session->id.buf);
		apt_list_push_back(session->request_queue,message,message->pool);
		return TRUE;
	}

	/* handle the request */
	session->active_request = message;
	rtsp_server_session_message_handle(server,session,message);
	return TRUE;
}
예제 #7
0
/** Generate MRCP descriptor by RTSP response */
MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_descriptor_generate_by_rtsp_response(const rtsp_message_t *request, const rtsp_message_t *response, apr_pool_t *pool, su_home_t *home)
{
	mrcp_session_descriptor_t *descriptor = NULL;
	const char *resource_name = request->start_line.common.request_line.resource_name;
	if(!resource_name) {
		return NULL;
	}
	
	if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) {
		if(rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE &&
			rtsp_header_property_check(&response->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE &&
			response->body.buf) {
			
			sdp_parser_t *parser;
			sdp_session_t *sdp;

			parser = sdp_parse(home,response->body.buf,response->body.length,0);
			sdp = sdp_session(parser);

			descriptor = mrcp_descriptor_generate_by_sdp_session(sdp,pool);
			if(descriptor) {
				apt_string_assign(&descriptor->resource_name,resource_name,pool);
				descriptor->resource_state = TRUE;
			}
			
			sdp_parser_free(parser);
		}
		else {
			descriptor = mrcp_session_descriptor_create(pool);
			if(descriptor) {
				apt_string_assign(&descriptor->resource_name,resource_name,pool);
				descriptor->resource_state = FALSE;
			}
		}
	}
	else if(request->start_line.common.request_line.method_id == RTSP_METHOD_TEARDOWN) {
		descriptor = mrcp_session_descriptor_create(pool);
		if(descriptor) {
			apt_string_assign(&descriptor->resource_name,resource_name,pool);
			descriptor->resource_state = FALSE;
		}
	}
	return descriptor;
}
예제 #8
0
/** Generate resource discovery descriptor by RTSP response */
MRCP_DECLARE(mrcp_session_descriptor_t*) mrcp_resource_discovery_response_generate(
											const rtsp_message_t *request, 
											const rtsp_message_t *response,
											const apr_table_t *resource_map,
											apr_pool_t *pool,
											su_home_t *home)
{
	mrcp_session_descriptor_t *descriptor = NULL;
	const char *resource_name = mrcp_name_get_by_rtsp_name(
					resource_map,
					request->start_line.common.request_line.resource_name);
	if(!resource_name) {
		return NULL;
	}
	
	descriptor = mrcp_session_descriptor_create(pool);
	apt_string_assign(&descriptor->resource_name,resource_name,pool);
	
	if(rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE &&
		rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE &&
		response->body.buf) {

		sdp_parser_t *parser;
		sdp_session_t *sdp;

		parser = sdp_parse(home,response->body.buf,response->body.length,0);
		sdp = sdp_session(parser);
		if(sdp) {
			mrcp_descriptor_generate_by_sdp_session(descriptor,sdp,0,pool);
			descriptor->resource_state = TRUE;
			descriptor->response_code = response->start_line.common.status_line.status_code;
		}
		else {
			apt_string_assign(&descriptor->resource_name,resource_name,pool);
			descriptor->resource_state = TRUE;
		}

		sdp_parser_free(parser);
	}
	else {
		descriptor->resource_state = FALSE;
	}
	return descriptor;
}
예제 #9
0
/** Header section handler */
static apt_bool_t rtsp_parser_on_header_complete(apt_message_parser_t *parser, apt_message_context_t *context)
{
	rtsp_message_t *rtsp_message = context->message;
	rtsp_header_fields_parse(&rtsp_message->header,rtsp_message->pool);

	if(context->body && rtsp_header_property_check(&rtsp_message->header,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE) {
		context->body->length = rtsp_message->header.content_length;
	}

	return TRUE;
}
static apt_bool_t mrcp_unirtsp_session_announce(mrcp_unirtsp_agent_t *agent, mrcp_unirtsp_session_t *session, rtsp_message_t *message)
{
	const char *resource_name = mrcp_name_get_by_rtsp_name(
		agent->config->resource_map,
		message->start_line.common.request_line.resource_name);
	apt_bool_t status = TRUE;

	if(session && resource_name &&
		rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_TYPE) == TRUE &&
		message->header.content_type == RTSP_CONTENT_TYPE_MRCP &&
		rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_CONTENT_LENGTH) == TRUE &&
		message->header.content_length > 0) {

		apt_text_stream_t text_stream;
		mrcp_parser_t *parser;
		apt_str_t resource_name_str;

		text_stream.text = message->body;
		text_stream.pos = text_stream.text.buf;
		apt_string_set(&resource_name_str,resource_name);

		parser = mrcp_parser_create(agent->sig_agent->resource_factory,session->mrcp_session->pool);
		mrcp_parser_resource_name_set(parser,&resource_name_str);
		if(mrcp_parser_run(parser,&text_stream) == MRCP_STREAM_MESSAGE_COMPLETE) {
			mrcp_message_t *mrcp_message = mrcp_parser_message_get(parser);
			mrcp_message->channel_id.session_id = message->header.session_id;
			status = mrcp_session_control_request(session->mrcp_session,mrcp_message);
		}
		else {
			/* error response */
			apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse MRCPv1 Message");
			status = FALSE;
		}
	}
	else {
		/* error response */
		status = FALSE;
	}
	return status;
}
예제 #11
0
/* Process incoming RTSP request */
static apt_bool_t rtsp_server_session_request_process(rtsp_server_t *server, rtsp_server_connection_t *rtsp_connection, rtsp_message_t *message)
{
	rtsp_server_session_t *session = NULL;
	if(message->start_line.message_type != RTSP_MESSAGE_TYPE_REQUEST) {
		/* received response to ANNOUNCE request/event */
		return TRUE;
	}

	if(rtsp_header_property_check(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID) != TRUE) {
		/* no session-id specified */
		session = rtsp_server_session_setup_process(server,rtsp_connection,message);
		if(session) {
			session->active_request = message;
			if(rtsp_server_session_message_handle(server,session,message) != TRUE) {
				rtsp_server_session_destroy(session);
			}
		}
		return TRUE;
	}

	/* existing session */
	session = apr_hash_get(
				rtsp_connection->session_table,
				message->header.session_id.buf,
				message->header.session_id.length);
	if(!session) {
		/* error case */
		apt_log(APT_PRIO_WARNING,"No Such RTSP Session <%s>",message->header.session_id.buf);
		return rtsp_server_error_respond(server,rtsp_connection,message,
								RTSP_STATUS_CODE_NOT_FOUND,
								RTSP_REASON_PHRASE_NOT_FOUND);
	}
	
	if(session->active_request) {
		apt_log(APT_PRIO_DEBUG,"Push RTSP Request to Queue <%s>",session->id.buf);
		apt_list_push_back(session->request_queue,message);
		return TRUE;
	}

	/* handle the request */
	session->active_request = message;
	rtsp_server_session_message_handle(server,session,message);
	return TRUE;
}
예제 #12
0
/* Process incoming RTSP response */
static apt_bool_t rtsp_client_session_response_process(rtsp_client_t *client, rtsp_client_session_t *session, rtsp_message_t *request, rtsp_message_t *response)
{
	const char *resource_name;
	if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP &&
		response->start_line.common.status_line.status_code == RTSP_STATUS_CODE_OK) {

		if(apr_hash_count(session->resource_table) == 0) {
			if(rtsp_header_property_check(&response->header,RTSP_HEADER_FIELD_SESSION_ID) == TRUE) {
				session->id = response->header.session_id;
				apt_log(RTSP_LOG_MARK,APT_PRIO_INFO,"Add RTSP Session " APT_PTRSID_FMT,
					session,
					session->id.buf);
				apr_hash_set(session->connection->session_table,session->id.buf,session->id.length,session);
			}
		}

		/* add resource */
		resource_name = request->start_line.common.request_line.resource_name;
		apr_hash_set(session->resource_table,resource_name,APR_HASH_KEY_STRING,request);
	}
	else if(request->start_line.common.request_line.method_id == RTSP_METHOD_TEARDOWN) {
		/* remove resource */
		resource_name = request->start_line.common.request_line.resource_name;
		apr_hash_set(session->resource_table,resource_name,APR_HASH_KEY_STRING,NULL);

		if(apr_hash_count(session->resource_table) == 0) {
			if(session->connection) {
				apt_log(RTSP_LOG_MARK,APT_PRIO_INFO,"Remove RTSP Session " APT_PTRSID_FMT,
					session,
					session->id.buf);
				apr_hash_set(session->connection->session_table,session->id.buf,session->id.length,NULL);
			}
		}
	}

	if(session->term_state != TERMINATION_STATE_INPROGRESS) {
		client->vtable->on_session_response(client,session,request,response);
	}

	return TRUE;
}