]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Set the AirPlay type to ap_1 and the timing type to ts_ntp when you get an ANNOUNCE...
authorMike Brady <4265913+mikebrady@users.noreply.github.com>
Thu, 11 Dec 2025 11:03:18 +0000 (11:03 +0000)
committerMike Brady <4265913+mikebrady@users.noreply.github.com>
Thu, 11 Dec 2025 11:03:18 +0000 (11:03 +0000)
rtsp.c

diff --git a/rtsp.c b/rtsp.c
index 30a7f54a9c7ea6f2e0700f291a190b0dbd7d3e4f..3918901e35e73d4307da24becd31f9cb5ab68d5c 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -1933,7 +1933,7 @@ struct pairings {
   uint8_t public_key[32];
 
   struct pairings *next;
-} * pairings;
+} *pairings;
 
 static struct pairings *pairing_find(const char *device_id) {
   for (struct pairings *pairing = pairings; pairing; pairing = pairing->next) {
@@ -2532,7 +2532,6 @@ void handle_setpeersx(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *res
 }
 #endif
 
-#ifndef CONFIG_AIRPLAY_2
 void handle_options(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
                     rtsp_message *resp) {
   debug_log_rtsp_message(2, "OPTIONS request", req);
@@ -2543,12 +2542,30 @@ void handle_options(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *
                  "PAUSE, FLUSH, TEARDOWN, "
                  "OPTIONS, GET_PARAMETER, SET_PARAMETER");
 }
-#endif
 
-#ifdef CONFIG_AIRPLAY_2
+void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
+                     rtsp_message *resp) {
+  debug(2, "Connection %d: TEARDOWN (Classic AirPlay)", conn->connection_number);
+  debug_log_rtsp_message(2, "TEARDOWN (Classic AirPlay) request", req);
 
-void handle_options(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
-                    rtsp_message *resp) {
+  // most of the cleanup here is done by the exiting player_thread, if any, and by the event
+  // receiver if and when it exits.
+
+  if (conn->player_thread) {
+    debug(1, "TEARDOWN is stopping a player...");
+    player_stop(conn);                    // this nulls the player_thread and cancels the threads...
+    activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
+  }
+
+  resp->respcode = 200;
+  msg_add_header(resp, "Connection", "close");
+  // debug(1,"Bogus exit for valgrind -- remember to comment it out!.");
+  // exit(EXIT_SUCCESS);
+}
+
+#ifdef CONFIG_AIRPLAY_2
+void handle_options_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
+                      rtsp_message *resp) {
   debug_log_rtsp_message(2, "OPTIONS request", req);
   debug(3, "Connection %d: OPTIONS", conn->connection_number);
   resp->respcode = 200;
@@ -2579,26 +2596,6 @@ void handle_teardown_2(rtsp_conn_info *conn, __attribute__((unused)) rtsp_messag
 }
 #endif
 
-void handle_teardown(rtsp_conn_info *conn, __attribute__((unused)) rtsp_message *req,
-                     rtsp_message *resp) {
-  debug(2, "Connection %d: TEARDOWN (Classic AirPlay)", conn->connection_number);
-  debug_log_rtsp_message(2, "TEARDOWN (Classic AirPlay) request", req);
-
-  // most of the cleanup here is done by the exiting player_thread, if any, and by the event
-  // receiver if and when it exits.
-
-  if (conn->player_thread) {
-    debug(1, "TEARDOWN is stopping a player...");
-    player_stop(conn);                    // this nulls the player_thread and cancels the threads...
-    activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
-  }
-
-  resp->respcode = 200;
-  msg_add_header(resp, "Connection", "close");
-  // debug(1,"Bogus exit for valgrind -- remember to comment it out!.");
-  // exit(EXIT_SUCCESS);
-}
-
 void handle_flush(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
   debug_log_rtsp_message(2, "FLUSH request", req);
   debug(3, "Connection %d: FLUSH", conn->connection_number);
@@ -4358,7 +4355,8 @@ static void handle_announce(rtsp_conn_info *conn, rtsp_message *req, rtsp_messag
           conn->connection_number, conn->client_ip_string, conn->client_rtsp_port,
           conn->self_ip_string, conn->self_rtsp_port);
 #endif
-
+    conn->airplay_type = ap_1;
+    conn->timing_type = ts_ntp;
     conn->stream.type = ast_unknown;
     resp->respcode = 200; // presumed OK
     char *pssid = NULL;
@@ -4574,7 +4572,7 @@ static struct method_handler {
   char *method;
   void (*ap1_handler)(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp); // for AirPlay 1
   void (*ap2_handler)(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp); // for AirPlay 2
-} method_handlers[] = {{"OPTIONS", handle_options, handle_options},
+} method_handlers[] = {{"OPTIONS", handle_options, handle_options_2},
                        {"ANNOUNCE", handle_announce, handle_announce},
                        {"FLUSH", handle_flush, handle_flush},
                        {"TEARDOWN", handle_teardown, handle_teardown_2},
@@ -4905,23 +4903,25 @@ void rtsp_conversation_thread_cleanup_function(void *arg) {
       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(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);
+    // give the event receiver a chance to exit normally, if it exists
+    if (conn->rtp_event_thread != NULL) {
+      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(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);
+      conn->rtp_event_thread = NULL;
     }
-    pthread_join(*conn->rtp_event_thread, NULL);
-    free(conn->rtp_event_thread);
-    conn->rtp_event_thread = NULL;
     conn->ap2_event_receiver_exited = 0;
     debug(3, "Connection %d: %s event thread deleted.", conn->connection_number,
           get_category_string(conn->airplay_stream_category));
@@ -5065,7 +5065,7 @@ static void *rtsp_conversation_thread_func(void *pconn) {
 
   while (conn->stop == 0) {
     pthread_testcancel();
-    int debug_level = 2; // for printing the request and response
+    int debug_level = 1; // for printing the request and response
 
     // check to see if a conn has been zeroed
 
@@ -5402,10 +5402,14 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
       memset(conn, 0, sizeof(rtsp_conn_info));
       conn->connection_number = RTSP_connection_index++;
       debug(2, "Connection %d is at: 0x%" PRIxPTR ".", conn->connection_number, conn);
+
+      // this means that the OPTIONS string we send before getting an ANNOUNCE is for AirPlay 2
 #ifdef CONFIG_AIRPLAY_2
       conn->airplay_type = ap_2;  // changed if an ANNOUNCE is received
       conn->timing_type = ts_ptp; // changed if an ANNOUNCE is received
 #else
+      conn->airplay_type = ap_1;
+      conn->timing_type = ts_ntp;
       conn->airplay_stream_category =
           classic_airplay_stream; // really just used for debug messages in Classic AirPlay builds
 #endif