/* Process session termination request */ static apt_bool_t rtsp_client_session_terminate_process(rtsp_client_t *client, rtsp_client_session_t *session) { rtsp_client_connection_t *rtsp_connection = session->connection; if(!rtsp_connection) { client->vtable->on_session_terminate_response(client,session); return FALSE; } if(session->active_request) { /* set termination state to requested */ session->term_state = TERMINATION_STATE_REQUESTED; } else { rtsp_client_session_resources_teardown(client,session); /* respond immediately if no resources left */ if(apr_hash_count(session->resource_table) == 0) { rtsp_client_session_terminate_respond(client,session); if(apr_hash_count(rtsp_connection->handle_table) == 0) { rtsp_client_connection_destroy(rtsp_connection); } } } return TRUE; }
/* RTSP connection disconnected */ static apt_bool_t rtsp_client_on_disconnect(rtsp_client_t *client, rtsp_client_connection_t *rtsp_connection) { rtsp_client_session_t *session; rtsp_message_t *request; rtsp_message_t *response; apr_size_t remaining_handles = 0; apr_size_t cancelled_requests = 0; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"TCP Peer Disconnected %s", rtsp_connection->base->id); apt_net_client_connection_close(client->task,rtsp_connection->base); /* Cancel in-progreess requests */ do { session = apt_list_pop_front(rtsp_connection->inprogress_request_queue); if(session && session->active_request) { request = session->active_request; session->active_request = NULL; cancelled_requests++; response = rtsp_response_create( request, RTSP_STATUS_CODE_INTERNAL_SERVER_ERROR, RTSP_REASON_PHRASE_INTERNAL_SERVER_ERROR, session->pool); rtsp_client_session_response_process(client,session,request,response); } } while(session); /* Walk through RTSP handles and raise termination event for them */ remaining_handles = apr_hash_count(rtsp_connection->handle_table); if(remaining_handles) { void *val; apr_hash_index_t *it; apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Terminate Remaining RTSP Handles [%d]",remaining_handles); it = apr_hash_first(rtsp_connection->base->pool,rtsp_connection->session_table); for(; it; it = apr_hash_next(it)) { apr_hash_this(it,NULL,NULL,&val); session = val; if(session) { rtsp_client_session_terminate_raise(client,session); } } remaining_handles = apr_hash_count(rtsp_connection->session_table); } if(!remaining_handles && !cancelled_requests) { rtsp_client_connection_destroy(client,rtsp_connection); } return TRUE; }
/* Respond to session termination request */ static apt_bool_t rtsp_client_session_terminate_respond(rtsp_client_t *client, rtsp_client_session_t *session) { rtsp_client_connection_t *rtsp_connection = session->connection; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remove RTSP Handle "APT_PTR_FMT,session); apr_hash_set(rtsp_connection->handle_table,session,sizeof(session),NULL); session->term_state = TERMINATION_STATE_NONE; client->vtable->on_session_terminate_response(client,session); if(apr_hash_count(rtsp_connection->handle_table) == 0) { rtsp_client_connection_destroy(client,rtsp_connection); } return TRUE; }
/** Return TRUE to proceed with the next message in the stream (if any) */ static apt_bool_t rtsp_client_message_handler(rtsp_client_connection_t *rtsp_connection, rtsp_message_t *message, apt_message_status_e status) { if(status != APT_MESSAGE_STATUS_COMPLETE) { /* message is not completely parsed, nothing to do */ return TRUE; } /* process parsed message */ if(message->start_line.message_type == RTSP_MESSAGE_TYPE_RESPONSE) { rtsp_message_t *request; rtsp_client_session_t *session; /* at first, pop in-progress request/session */ if(rtsp_client_request_pop(rtsp_connection,message,&request,&session) == FALSE) { apt_log(RTSP_LOG_MARK,APT_PRIO_WARNING,"Unexpected RTSP Response Received CSeq:%"APR_SIZE_T_FMT, message->header.cseq); return TRUE; } /* next, process session response */ rtsp_client_session_response_process(rtsp_connection->client,session,request,message); /* process session pending requests */ if(rtsp_client_session_pending_requests_process(rtsp_connection->client,session) == FALSE) { /* no in-progress request, check the termination state now */ if(session->term_state != TERMINATION_STATE_NONE) { if(session->term_state == TERMINATION_STATE_REQUESTED) { rtsp_client_session_resources_teardown(rtsp_connection->client,session); } /* respond if no resources left */ if(apr_hash_count(session->resource_table) == 0) { rtsp_client_session_terminate_respond(rtsp_connection->client,session); if(apr_hash_count(rtsp_connection->handle_table) == 0) { rtsp_client_connection_destroy(rtsp_connection); /* return FALSE to indicate connection has been destroyed */ return FALSE; } } } } } else if(message->start_line.message_type == RTSP_MESSAGE_TYPE_REQUEST) { rtsp_client_session_event_process(rtsp_connection->client,rtsp_connection,message); } return TRUE; }