Move clock setup and start from Setup Phase 1 to Setup Phase 2. clear_all_conns now clears every type of connection, not just airplay. Clean up, rename and remove some old stuff and quieten yet more debug messages.
This commit is contained in:
@@ -487,7 +487,7 @@ static void track_thread(rtsp_conn_info *conn) {
|
||||
}
|
||||
|
||||
// note: connection numbers start at 1, so an except_this_one value of zero means "all threads"
|
||||
void cancel_all_RTSP_threads(airplay_stream_c stream_category, int except_this_one) {
|
||||
void cancel_all_RTSP_threads(__attribute((unused)) airplay_stream_c stream_category, int except_this_one) {
|
||||
// if the stream category is unspecified_stream_category
|
||||
// all categories are elegible for cancellation
|
||||
// otherwise just the category itself
|
||||
@@ -495,21 +495,17 @@ void cancel_all_RTSP_threads(airplay_stream_c stream_category, int except_this_o
|
||||
int i;
|
||||
for (i = 0; i < nconns; i++) {
|
||||
if ((conns[i] != NULL) && (conns[i]->running != 0) &&
|
||||
(conns[i]->connection_number != except_this_one) &&
|
||||
((stream_category == unspecified_stream_category) ||
|
||||
(stream_category == conns[i]->airplay_stream_category))) {
|
||||
(conns[i]->connection_number != except_this_one)) {
|
||||
pthread_cancel(conns[i]->thread);
|
||||
debug(1, "Connection %d: cancelled.", conns[i]->connection_number);
|
||||
debug(1, "Connection %d: %s cancelled.", conns[i]->connection_number, get_category_string(conns[i]->airplay_stream_category));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nconns; i++) {
|
||||
if ((conns[i] != NULL) && (conns[i]->running != 0) &&
|
||||
(conns[i]->connection_number != except_this_one) &&
|
||||
((stream_category == unspecified_stream_category) ||
|
||||
(stream_category == conns[i]->airplay_stream_category))) {
|
||||
debug(1, "Connection %d: joining...", conns[i]->connection_number);
|
||||
if ((conns[i] != NULL) &&
|
||||
(conns[i]->connection_number != except_this_one)) {
|
||||
debug(1, "Connection %d: %s joining....", conns[i]->connection_number, get_category_string(conns[i]->airplay_stream_category));
|
||||
pthread_join(conns[i]->thread, NULL);
|
||||
debug(1, "Connection %d: joined.", conns[i]->connection_number);
|
||||
debug(1, "Connection %d: %s joined.", conns[i]->connection_number, get_category_string(conns[i]->airplay_stream_category));
|
||||
free(conns[i]);
|
||||
conns[i] = NULL;
|
||||
}
|
||||
@@ -934,31 +930,6 @@ ssize_t write_encrypted(int fd, pair_cipher_bundle *ctx, const void *buf, size_t
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
static ssize_t write_encrypted(rtsp_conn_info *conn, const void *buf, size_t count) {
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
|
||||
ssize_t ret =
|
||||
pair_encrypt(&encrypted, &encrypted_len, buf, count, conn->ap2_pairing_context.cipher_ctx);
|
||||
if (ret < 0) {
|
||||
debug(1, pair_cipher_errmsg(conn->ap2_pairing_context.cipher_ctx));
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t remain = encrypted_len;
|
||||
while (remain > 0) {
|
||||
ssize_t wrote = write(conn->fd, encrypted + (encrypted_len - remain), remain);
|
||||
if (wrote <= 0) {
|
||||
free(encrypted);
|
||||
return wrote;
|
||||
}
|
||||
remain -= wrote;
|
||||
}
|
||||
free(encrypted);
|
||||
return count;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
ssize_t read_from_rtsp_connection(rtsp_conn_info *conn, void *buf, size_t count) {
|
||||
@@ -1732,7 +1703,7 @@ void handle_flushbuffered(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
|
||||
conn->connection_number, flushUntilTS, flushUntilSeq & 0x7fffff);
|
||||
conn->ap2_play_enabled = 0; // stop trying to play audio
|
||||
ptp_send_control_message_string(
|
||||
"P"); // signify clock no longer valid and will be restarted by a subsequent play
|
||||
"P"); // "P"ause signify clock no longer valid and will be restarted by a subsequent play
|
||||
} else {
|
||||
// look for a record slot that isn't in use
|
||||
unsigned int i = 0;
|
||||
@@ -2537,103 +2508,6 @@ void handle_options(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *
|
||||
"OPTIONS, POST, GET, PUT");
|
||||
}
|
||||
|
||||
/*
|
||||
void teardown_phase_one(rtsp_conn_info *conn) {
|
||||
// this can be called more than once on the same connection --
|
||||
// by the player itself but also by the play session being killed
|
||||
if (conn->player_thread) {
|
||||
player_stop(conn); // this nulls the player_thread
|
||||
activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
|
||||
}
|
||||
if (conn->session_key) {
|
||||
free(conn->session_key);
|
||||
conn->session_key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void teardown_phase_two(rtsp_conn_info *conn) {
|
||||
// we are being asked to disconnect
|
||||
// this can be called more than once on the same connection --
|
||||
// by the player itself but also by the play seesion being killed
|
||||
debug(3, "Connection %d: TEARDOWN %s connection.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
// if (conn->airplay_stream_category == remote_control_stream) {
|
||||
if (conn->rtp_data_thread) {
|
||||
debug(3, "Connection %d: TEARDOWN %s Delete Data Thread.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
pthread_cancel(*conn->rtp_data_thread);
|
||||
pthread_join(*conn->rtp_data_thread, NULL);
|
||||
free(conn->rtp_data_thread);
|
||||
conn->rtp_data_thread = NULL;
|
||||
}
|
||||
if (conn->data_socket) {
|
||||
debug(3, "Connection %d: TEARDOWN %s Close Data Socket.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
close(conn->data_socket);
|
||||
conn->data_socket = 0;
|
||||
}
|
||||
//}
|
||||
|
||||
if (conn->rtp_event_thread) {
|
||||
debug(3, "Connection %d: TEARDOWN %s Delete Event Thread.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
pthread_cancel(*conn->rtp_event_thread);
|
||||
pthread_join(*conn->rtp_event_thread, NULL);
|
||||
free(conn->rtp_event_thread);
|
||||
debug(3, "Connection %d: TEARDOWN %s Event Thread deleted.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
conn->rtp_event_thread = NULL;
|
||||
}
|
||||
if (conn->event_socket) {
|
||||
debug(3, "Connection %d: TEARDOWN %s Close Event Socket.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
close(conn->event_socket);
|
||||
conn->event_socket = 0;
|
||||
}
|
||||
|
||||
// if we are closing a PTP stream only, do this
|
||||
if (conn->airplay_stream_category == ptp_stream) {
|
||||
if (conn->airplay_gid != NULL) {
|
||||
free(conn->airplay_gid);
|
||||
conn->airplay_gid = NULL;
|
||||
|
||||
#ifdef CONFIG_METADATA
|
||||
// this is here to ensure it's only performed once during a teardown of a ptp stream
|
||||
send_ssnc_metadata('disc', conn->client_ip_string, strlen(conn->client_ip_string), 1);
|
||||
#endif
|
||||
}
|
||||
conn->groupContainsGroupLeader = 0;
|
||||
if (conn->dacp_active_remote != NULL) {
|
||||
free(conn->dacp_active_remote);
|
||||
conn->dacp_active_remote = NULL;
|
||||
}
|
||||
if (conn->ap2_client_name) {
|
||||
free(conn->ap2_client_name);
|
||||
conn->ap2_client_name = NULL;
|
||||
}
|
||||
#ifdef CONFIG_FFMPEG
|
||||
clear_decoding_chain(conn);
|
||||
#endif
|
||||
clear_ptp_clock();
|
||||
}
|
||||
|
||||
// only update these things if you're (still) the principal conn
|
||||
pthread_rwlock_wrlock(&principal_conn_lock); // don't let the principal_conn be changed
|
||||
pthread_cleanup_push(rwlock_unlock, (void *)&principal_conn_lock);
|
||||
if (principal_conn == conn) {
|
||||
if (conn->airplay_stream_category == ptp_stream) {
|
||||
config.airplay_statusflags &= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
|
||||
build_bonjour_strings(conn);
|
||||
debug(3, "Connection %d: teardown mdns_update on %s.", conn->connection_number,
|
||||
get_category_string(conn->airplay_stream_category));
|
||||
mdns_update(NULL, secondary_txt_records);
|
||||
}
|
||||
principal_conn = NULL; // stop being principal_conn
|
||||
}
|
||||
pthread_cleanup_pop(1); // release the principal_conn lock
|
||||
}
|
||||
*/
|
||||
|
||||
void handle_teardown_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
|
||||
rtsp_message *resp) {
|
||||
|
||||
@@ -2653,10 +2527,16 @@ void handle_teardown_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_messag
|
||||
}
|
||||
#endif
|
||||
|
||||
void teardown(rtsp_conn_info *conn) {
|
||||
debug(2, "Connection %d: TEARDOWN (Classic AirPlay).", conn->connection_number);
|
||||
player_stop(conn);
|
||||
activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
|
||||
void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
|
||||
rtsp_message *resp) {
|
||||
debug(1, "Connection %d: TEARDOWN (Classic AirPlay)", conn->connection_number);
|
||||
debug_log_rtsp_message(1, "TEARDOWN (Classic AirPlay) request", req);
|
||||
|
||||
if (conn->player_thread) {
|
||||
player_stop(conn); // this nulls the player_thread and cancels the threads...
|
||||
activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
|
||||
}
|
||||
|
||||
if (conn->dacp_active_remote != NULL) {
|
||||
free(conn->dacp_active_remote);
|
||||
conn->dacp_active_remote = NULL;
|
||||
@@ -2673,17 +2553,7 @@ void teardown(rtsp_conn_info *conn) {
|
||||
principal_conn = NULL; // stop being principal_conn
|
||||
}
|
||||
pthread_cleanup_pop(1); // release the principal_conn lock
|
||||
}
|
||||
|
||||
void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
|
||||
rtsp_message *resp) {
|
||||
debug(1, "Connection %d: TEARDOWN", conn->connection_number);
|
||||
debug_log_rtsp_message(1, "TEARDOWN request", req);
|
||||
|
||||
debug(3,
|
||||
"TEARDOWN: synchronously terminating the player thread of RTSP conversation thread %d (2).",
|
||||
conn->connection_number);
|
||||
teardown(conn);
|
||||
|
||||
#ifdef CONFIG_FFMPEG
|
||||
clear_decoding_chain(conn);
|
||||
#endif
|
||||
@@ -2962,8 +2832,9 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
|
||||
|
||||
// debug(1,"initial timing peer command: \"%s\".", timing_list_message);
|
||||
// ptp_send_control_message_string(timing_list_message);
|
||||
set_client_as_ptp_clock(conn);
|
||||
ptp_send_control_message_string("B"); // signify clock dependability period is
|
||||
// deferring this until play is about to start
|
||||
// set_client_as_ptp_clock(conn);
|
||||
// ptp_send_control_message_string("B"); // signify clock dependability period is
|
||||
// "B"eginning (or continuing)
|
||||
plist_dict_set_item(timingPeerInfoPlist, "Addresses", addresses);
|
||||
plist_dict_set_item(timingPeerInfoPlist, "ID",
|
||||
@@ -3094,6 +2965,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
|
||||
activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
|
||||
}
|
||||
|
||||
set_client_as_ptp_clock(conn);
|
||||
ptp_send_control_message_string(
|
||||
"B"); // signify clock dependability period is "B"eginning (or continuing)
|
||||
plist_t stream0 = plist_array_get_item(streams, 0);
|
||||
@@ -5000,15 +4872,20 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
|
||||
free(conn->session_key);
|
||||
conn->session_key = NULL;
|
||||
}
|
||||
|
||||
|
||||
// give the event receiver a chance to exit normally
|
||||
uint64_t event_receiver_start_wait_time = get_absolute_time_in_ns();
|
||||
int64_t event_receiver_wait_time = 0;
|
||||
do {
|
||||
if (conn->ap2_event_receiver_exited == 0)
|
||||
usleep(50000);
|
||||
event_receiver_wait_time = get_absolute_time_in_ns() - event_receiver_start_wait_time;
|
||||
} while ((conn->ap2_event_receiver_exited == 0) && (event_receiver_wait_time < 2000000000L));
|
||||
|
||||
if (conn->ap2_event_receiver_exited == 0) {
|
||||
debug(3, "waiting for event receiver to exit");
|
||||
usleep(2000000);
|
||||
if (conn->ap2_event_receiver_exited == 0) {
|
||||
debug(1, "Connection %d: %s event receiver has not exited, so cancelling it.",
|
||||
conn->connection_number, get_category_string(conn->airplay_stream_category));
|
||||
pthread_cancel(*conn->rtp_event_thread);
|
||||
}
|
||||
debug(1, "Connection %d: %s event receiver has not exited, so cancelling it.",
|
||||
conn->connection_number, get_category_string(conn->airplay_stream_category));
|
||||
pthread_cancel(*conn->rtp_event_thread);
|
||||
}
|
||||
pthread_join(*conn->rtp_event_thread, NULL);
|
||||
free(conn->rtp_event_thread);
|
||||
|
||||
Reference in New Issue
Block a user