static apt_bool_t rtsp_server_message_handler(rtsp_server_connection_t *rtsp_connection, rtsp_message_t *message, apt_message_status_e status) { if(status == APT_MESSAGE_STATUS_COMPLETE) { /* message is completely parsed */ apt_str_t *destination; destination = &message->header.transport.destination; if(!destination->buf && rtsp_connection->client_ip) { apt_string_assign(destination,rtsp_connection->client_ip,rtsp_connection->pool); } rtsp_server_session_request_process(rtsp_connection->server,rtsp_connection,message); } else if(status == APT_MESSAGE_STATUS_INVALID) { /* error case */ rtsp_message_t *response; apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse RTSP Data"); if(message) { response = rtsp_response_create(message,RTSP_STATUS_CODE_BAD_REQUEST, RTSP_REASON_PHRASE_BAD_REQUEST,message->pool); if(rtsp_server_message_send(rtsp_connection->server,rtsp_connection,response) == FALSE) { apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Send RTSP Response"); } } } return TRUE; }
/* Finally terminate RTSP session */ static apt_bool_t rtsp_server_session_do_terminate(rtsp_server_t *server, rtsp_server_session_t *session) { rtsp_server_connection_t *rtsp_connection = session->connection; if(session->active_request) { rtsp_message_t *response = rtsp_response_create(session->active_request, RTSP_STATUS_CODE_OK,RTSP_REASON_PHRASE_OK,session->active_request->pool); if(response) { if(session->id.buf) { response->header.session_id = session->id; rtsp_header_property_add(&response->header,RTSP_HEADER_FIELD_SESSION_ID,response->pool); } if(rtsp_connection) { rtsp_server_message_send(server,rtsp_connection,response); } } } apt_log(RTSP_LOG_MARK,APT_PRIO_INFO,"Remove RTSP Session " APT_SID_FMT,session->id.buf); if(rtsp_connection) { apr_hash_set(rtsp_connection->session_table,session->id.buf,session->id.length,NULL); } rtsp_server_session_destroy(session); if(rtsp_connection && !rtsp_connection->sock) { if(apr_hash_count(rtsp_connection->session_table) == 0) { rtsp_server_connection_destroy(rtsp_connection); } } return TRUE; }
/* Receive RTSP message through RTSP connection */ static apt_bool_t rtsp_server_message_receive(apt_net_server_task_t *task, apt_net_server_connection_t *connection) { rtsp_server_t *server = apt_net_server_task_object_get(task); char buffer[RTSP_MESSAGE_MAX_SIZE]; apt_bool_t more_messages_on_buffer = FALSE; apr_status_t status; apt_text_stream_t text_stream; rtsp_message_t *message; if(!connection || !connection->sock) { return FALSE; } text_stream.text.buf = buffer; text_stream.text.length = sizeof(buffer)-1; status = apr_socket_recv(connection->sock, text_stream.text.buf, &text_stream.text.length); if(status == APR_EOF || text_stream.text.length == 0) { return apt_net_server_connection_close(task,connection); } text_stream.text.buf[text_stream.text.length] = '\0'; text_stream.pos = text_stream.text.buf; apt_log(APT_PRIO_INFO,"Receive RTSP Message size=%lu\n%s",text_stream.text.length,text_stream.text.buf); do { message = rtsp_message_create(RTSP_MESSAGE_TYPE_UNKNOWN,connection->pool); if(rtsp_message_parse(message,&text_stream) == TRUE) { apt_str_t *destination = &message->header.transport.destination; if(!destination->buf && connection->client_ip) { apt_string_assign(destination,connection->client_ip,connection->pool); } rtsp_server_session_request_process(server,connection->obj,message); } else { rtsp_message_t *response; apt_log(APT_PRIO_WARNING,"Failed to Parse RTSP Message"); response = rtsp_response_create(message,RTSP_STATUS_CODE_BAD_REQUEST, RTSP_REASON_PHRASE_BAD_REQUEST,message->pool); if(rtsp_server_message_send(server,connection,response) == FALSE) { apt_log(APT_PRIO_WARNING,"Failed to Send RTSP Response"); } } more_messages_on_buffer = FALSE; if(text_stream.text.length > (apr_size_t)(text_stream.pos - text_stream.text.buf)) { /* there are more RTSP messages to signal */ more_messages_on_buffer = TRUE; text_stream.text.length -= text_stream.pos - text_stream.text.buf; text_stream.text.buf = text_stream.pos; apt_log(APT_PRIO_DEBUG,"Saving Remaining Buffer for Next Message"); } } while(more_messages_on_buffer); return TRUE; }
static apt_bool_t rtsp_server_error_respond(rtsp_server_t *server, rtsp_server_connection_t *rtsp_connection, rtsp_message_t *request, rtsp_status_code_e status_code, rtsp_reason_phrase_e reason) { /* send error response to client */ rtsp_message_t *response = rtsp_response_create(request,status_code,reason,request->pool); if(rtsp_server_message_send(server,rtsp_connection,response) == FALSE) { apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Failed to Send RTSP Response"); return FALSE; } return TRUE; }
/* Process outgoing RTSP response */ static apt_bool_t rtsp_server_session_response_process(rtsp_server_t *server, rtsp_server_session_t *session, rtsp_message_t *message) { if(message->start_line.message_type == RTSP_MESSAGE_TYPE_REQUEST) { /* RTSP ANNOUNCE request (asynch event) */ message->start_line.common.request_line.url = session->url; if(session->id.buf) { message->header.session_id = session->id; rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); } rtsp_server_message_send(server,session->connection->base,message); return TRUE; } if(session->id.buf) { message->header.session_id = session->id; rtsp_header_property_add(&message->header.property_set,RTSP_HEADER_FIELD_SESSION_ID); } rtsp_server_message_send(server,session->connection->base,message); if(session->active_request) { rtsp_message_t *request = session->active_request; if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) { if(message->start_line.common.status_line.status_code != RTSP_STATUS_CODE_OK) { rtsp_server_session_terminate_request(server,session); } } else if(request->start_line.common.request_line.method_id == RTSP_METHOD_DESCRIBE) { rtsp_server_session_terminate_request(server,session); } } session->active_request = apt_list_pop_front(session->request_queue); if(session->active_request) { rtsp_server_session_message_handle(server,session,session->active_request); } return TRUE; }
/* Process outgoing RTSP response */ static apt_bool_t rtsp_server_session_response_process(rtsp_server_t *server, rtsp_server_session_t *session, rtsp_message_t *message) { apt_bool_t terminate = FALSE; rtsp_message_t *request = NULL; if(message->start_line.message_type == RTSP_MESSAGE_TYPE_REQUEST) { /* RTSP ANNOUNCE request (asynch event) */ const char *resource_name = message->start_line.common.request_line.resource_name; if(resource_name) { request = apr_hash_get(session->resource_table,resource_name,APR_HASH_KEY_STRING); } if(!request) { return FALSE; } message->start_line.common.request_line.url = request->start_line.common.request_line.url; message->header.cseq = session->last_cseq; rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_CSEQ,message->pool); if(session->id.buf) { message->header.session_id = session->id; rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_SESSION_ID,message->pool); } rtsp_server_message_send(server,session->connection,message); return TRUE; } if(!session->active_request) { /* unexpected response */ return FALSE; } request = session->active_request; if(request->start_line.common.request_line.method_id == RTSP_METHOD_DESCRIBE) { terminate = TRUE; } else { if(session->id.buf) { message->header.session_id = session->id; rtsp_header_property_add(&message->header,RTSP_HEADER_FIELD_SESSION_ID,message->pool); } if(request->start_line.common.request_line.method_id == RTSP_METHOD_SETUP) { if(message->start_line.common.status_line.status_code == RTSP_STATUS_CODE_OK) { /* add resource */ const char *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(apr_hash_count(session->resource_table) == 0) { terminate = TRUE; } } } session->last_cseq = message->header.cseq; rtsp_server_message_send(server,session->connection,message); if(terminate == TRUE) { session->active_request = NULL; rtsp_server_session_terminate_request(server,session); return TRUE; } session->active_request = apt_list_pop_front(session->request_queue); if(session->active_request) { rtsp_server_session_message_handle(server,session,session->active_request); } return TRUE; }