/* 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); }
/** 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; }
/** 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; }
/** 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; }
/* 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; }
/** 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; }
/** 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; }
/** 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; }
/* 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; }
/* 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; }