2 * RTSP protocol handler. This file is part of Shairport Sync
3 * Copyright (c) James Laird 2013
5 * Modifications associated with audio synchronization, multithreading and
6 * metadata handling copyright (c) Mike Brady 2014-2023
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or
14 * sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
30 #include <arpa/inet.h>
39 #include <netinet/in.h>
40 #include <netinet/tcp.h>
46 #include <sys/select.h>
47 #include <sys/socket.h>
49 #include <sys/types.h>
52 #include <sys/ioctl.h>
54 #include "activity_monitor.h"
58 #include <openssl/evp.h>
62 #include <mbedtls/md5.h>
63 #include <mbedtls/version.h>
66 #ifdef CONFIG_POLARSSL
67 #include <polarssl/md5.h>
75 #ifdef CONFIG_METADATA_HUB
76 #include "metadata_hub.h"
84 #define INETx_ADDRSTRLEN INET6_ADDRSTRLEN
86 #define INETx_ADDRSTRLEN INET_ADDRSTRLEN
89 #ifdef CONFIG_AIRPLAY_2
90 #include "pair_ap/pair.h"
91 #include "plist/plist.h"
92 #include "plist_xml_strings.h"
93 #include "ptp-utilities.h"
95 #ifdef HAVE_LIBPLIST_GE_2_3_0
96 #define plist_from_memory(plist_data, length, plist) \
97 plist_from_memory((plist_data), (length), (plist), NULL)
101 #ifdef CONFIG_DBUS_INTERFACE
102 #include "dbus-service.h"
107 // mDNS advertisement strings
109 // Create these strings and then keep them updated.
110 // When necessary, update the mDNS service records, using e.g. Avahi
111 // from these sources.
113 char *txt_records
[64];
114 char *secondary_txt_records
[64];
116 char firmware_version
[64];
117 char ap1_featuresString
[64];
119 #ifdef CONFIG_AIRPLAY_2
120 char deviceIdString
[64];
121 char featuresString
[64];
122 char statusflagsString
[32];
127 #define METADATA_SNDBUF (4 * 1024 * 1024)
129 enum rtsp_read_request_response
{
130 rtsp_read_request_response_ok
,
131 rtsp_read_request_response_immediate_shutdown_requested
,
132 rtsp_read_request_response_bad_packet
,
133 rtsp_read_request_response_channel_closed
,
134 rtsp_read_request_response_read_error
,
135 rtsp_read_request_response_error
138 static int nconns
= 0; // i.e. the size if the conns array
139 rtsp_conn_info
*principal_conn
;
140 rtsp_conn_info
**conns
;
142 int metadata_running
= 0;
144 // always lock this when trying to make a conn the principal conn,
145 // e.g. during an ANNOUNCE (Classic AirPlay) or SETUP (AirPlay 2)
146 pthread_mutex_t principal_conn_acquisition_lock
= PTHREAD_MUTEX_INITIALIZER
;
148 // always lock this when accessing the principal conn value
149 pthread_mutex_t principal_conn_lock
= PTHREAD_MUTEX_INITIALIZER
;
151 // always lock this when accessing the list of connection threads
152 pthread_mutex_t conns_lock
= PTHREAD_MUTEX_INITIALIZER
;
154 // every time we want to retain or release a reference count, lock it with this
155 // if a reference count is read as zero, it means the it's being deallocated.
156 static pthread_mutex_t reference_counter_lock
= PTHREAD_MUTEX_INITIALIZER
;
158 // only one thread is allowed to use the player at once.
159 // it monitors the request variable (at least when interrupted)
160 // static pthread_mutex_t playing_mutex = PTHREAD_MUTEX_INITIALIZER;
161 // static int please_shutdown = 0;
162 // static pthread_t playing_thread = 0;
164 int RTSP_connection_index
= 1;
166 #ifdef CONFIG_METADATA
168 pthread_mutex_t pc_queue_lock
;
169 pthread_cond_t pc_queue_item_added_signal
;
170 pthread_cond_t pc_queue_item_removed_signal
;
172 size_t item_size
; // number of bytes in each item
173 uint32_t count
; // number of items in the queue
174 uint32_t capacity
; // maximum number of items
175 uint32_t toq
; // first item to take
176 uint32_t eoq
; // free space at end of queue
177 void *items
; // a pointer to where the items are actually stored
178 } pc_queue
; // producer-consumer queue
181 static int msg_indexes
= 1;
185 uint32_t referenceCount
; // we might start using this...
186 unsigned int nheaders
;
190 uint32_t contentlength
;
201 #ifdef CONFIG_AIRPLAY_2
203 int add_pstring_to_malloc(const char *s
, void **allocation
, size_t *size
) {
205 void *p
= *allocation
;
207 p
= malloc(strlen(s
) + 1);
209 debug(1, "error allocating memory");
212 *size
= *size
+ strlen(s
) + 1;
213 uint8_t *b
= (uint8_t *)p
;
216 memcpy(p
, s
, strlen(s
));
220 p
= realloc(p
, *size
+ strlen(s
) + 1);
221 if (p
== NULL
) { // assuming we never allocate a zero byte space
222 debug(1, "error reallocating memory");
225 uint8_t *b
= (uint8_t *)p
+ *size
;
228 memcpy(p
, s
, strlen(s
));
229 *size
= *size
+ strlen(s
) + 1;
236 static void pkString_make(char *str
, size_t str_size
, const char *device_id
) {
237 uint8_t public_key
[32];
238 if (str_size
< 2 * sizeof(public_key
) + 1) {
239 warn("Insufficient string size");
243 pair_public_key_get(PAIR_SERVER_HOMEKIT
, public_key
, device_id
);
245 for (size_t i
= 0; i
< sizeof(public_key
); i
++)
246 ptr
+= sprintf(ptr
, "%02x", public_key
[i
]);
250 #ifdef CONFIG_AIRPLAY_2
251 void build_bonjour_strings(rtsp_conn_info
*conn
) {
253 void build_bonjour_strings(__attribute((unused
)) rtsp_conn_info
*conn
) {
256 int entry_number
= 0;
258 // make up a firmware version
259 #ifdef CONFIG_USE_GIT_VERSION_STRING
260 if (git_version_string
[0] != '\0')
261 snprintf(firmware_version
, sizeof(firmware_version
), "fv=%s", git_version_string
);
264 snprintf(firmware_version
, sizeof(firmware_version
), "fv=%s", PACKAGE_VERSION
);
266 #ifdef CONFIG_AIRPLAY_2
267 uint64_t features_hi
= config
.airplay_features
;
268 features_hi
= (features_hi
>> 32) & 0xffffffff;
269 uint64_t features_lo
= config
.airplay_features
;
270 features_lo
= features_lo
& 0xffffffff;
271 snprintf(ap1_featuresString
, sizeof(ap1_featuresString
), "ft=0x%" PRIX64
",0x%" PRIX64
"",
272 features_lo
, features_hi
);
273 snprintf(pkString
, sizeof(pkString
), "pk=");
274 pkString_make(pkString
+ strlen("pk="), sizeof(pkString
) - strlen("pk="),
275 config
.airplay_device_id
);
277 txt_records
[entry_number
++] = "cn=0,1";
278 txt_records
[entry_number
++] = "da=true";
279 txt_records
[entry_number
++] = "et=0,1";
280 txt_records
[entry_number
++] = ap1_featuresString
;
281 txt_records
[entry_number
++] = firmware_version
;
282 #ifdef CONFIG_METADATA
283 if (config
.get_coverart
== 0)
284 txt_records
[entry_number
++] = "md=0,2";
286 txt_records
[entry_number
++] = "md=0,1,2";
288 txt_records
[entry_number
++] = "am=Shairport Sync";
289 txt_records
[entry_number
++] = "sf=0x4";
290 txt_records
[entry_number
++] = "tp=UDP";
291 txt_records
[entry_number
++] = "vn=65537";
292 txt_records
[entry_number
++] = "vs=366.0";
293 txt_records
[entry_number
++] = pkString
;
294 txt_records
[entry_number
++] = NULL
;
297 // here, just replicate what happens in mdns.h when using those #defines
298 txt_records
[entry_number
++] = "sf=0x4";
299 txt_records
[entry_number
++] = firmware_version
;
300 txt_records
[entry_number
++] = "am=ShairportSync";
301 txt_records
[entry_number
++] = "vs=105.1";
302 txt_records
[entry_number
++] = "tp=TCP,UDP";
303 txt_records
[entry_number
++] = "vn=65537";
304 #ifdef CONFIG_METADATA
305 if (config
.get_coverart
== 0)
306 txt_records
[entry_number
++] = "md=0,2";
308 txt_records
[entry_number
++] = "md=0,1,2";
310 txt_records
[entry_number
++] = "ss=16";
311 txt_records
[entry_number
++] = "sr=44100";
312 txt_records
[entry_number
++] = "da=true";
313 txt_records
[entry_number
++] = "sv=false";
314 txt_records
[entry_number
++] = "et=0,1";
315 txt_records
[entry_number
++] = "ek=1";
316 txt_records
[entry_number
++] = "cn=0,1";
317 txt_records
[entry_number
++] = "ch=2";
318 txt_records
[entry_number
++] = "txtvers=1";
319 if (config
.password
== 0)
320 txt_records
[entry_number
++] = "pw=false";
322 txt_records
[entry_number
++] = "pw=true";
323 txt_records
[entry_number
++] = NULL
;
326 #ifdef CONFIG_AIRPLAY_2
327 // make up a secondary set of text records
330 secondary_txt_records
[entry_number
++] = "srcvers=366.0";
331 snprintf(deviceIdString
, sizeof(deviceIdString
), "deviceid=%s", config
.airplay_device_id
);
332 secondary_txt_records
[entry_number
++] = deviceIdString
;
333 snprintf(featuresString
, sizeof(featuresString
), "features=0x%" PRIX64
",0x%" PRIX64
"",
334 features_lo
, features_hi
);
335 secondary_txt_records
[entry_number
++] = featuresString
;
336 snprintf(statusflagsString
, sizeof(statusflagsString
), "flags=0x%" PRIX32
,
337 config
.airplay_statusflags
);
339 secondary_txt_records
[entry_number
++] = statusflagsString
;
340 secondary_txt_records
[entry_number
++] = "protovers=1.1";
341 secondary_txt_records
[entry_number
++] = "acl=0";
342 secondary_txt_records
[entry_number
++] = "rsf=0x0";
343 secondary_txt_records
[entry_number
++] = firmware_version
;
344 secondary_txt_records
[entry_number
++] = "model=Shairport Sync";
345 snprintf(piString
, sizeof(piString
), "pi=%s", config
.airplay_pi
);
346 secondary_txt_records
[entry_number
++] = piString
;
347 if ((conn
!= NULL
) && (conn
->airplay_gid
!= 0)) {
348 snprintf(gidString
, sizeof(gidString
), "gid=%s", conn
->airplay_gid
);
350 snprintf(gidString
, sizeof(gidString
), "gid=%s", config
.airplay_pi
);
352 secondary_txt_records
[entry_number
++] = gidString
;
353 if ((conn
!= NULL
) && (conn
->groupContainsGroupLeader
!= 0))
354 secondary_txt_records
[entry_number
++] = "gcgl=1";
356 secondary_txt_records
[entry_number
++] = "gcgl=0";
357 if ((conn
!= NULL
) && (conn
->airplay_gid
!= 0)) // if it's in a group
358 secondary_txt_records
[entry_number
++] = "isGroupLeader=0";
359 secondary_txt_records
[entry_number
++] = pkString
;
360 secondary_txt_records
[entry_number
++] = NULL
;
364 #ifdef CONFIG_METADATA
370 rtsp_message
*carrier
;
373 void pc_queue_init(pc_queue
*the_queue
, char *items
, size_t item_size
, uint32_t number_of_items
,
376 debug(2, "Creating metadata queue \"%s\".", name
);
378 debug(1, "Creating an unnamed metadata queue.");
379 pthread_mutex_init(&the_queue
->pc_queue_lock
, NULL
);
380 pthread_cond_init(&the_queue
->pc_queue_item_added_signal
, NULL
);
381 pthread_cond_init(&the_queue
->pc_queue_item_removed_signal
, NULL
);
382 the_queue
->item_size
= item_size
;
383 the_queue
->items
= items
;
384 the_queue
->count
= 0;
385 the_queue
->capacity
= number_of_items
;
389 the_queue
->name
= NULL
;
391 the_queue
->name
= strdup(name
);
394 void pc_queue_delete(pc_queue
*the_queue
) {
396 debug(2, "Deleting metadata queue \"%s\".", the_queue
->name
);
398 debug(1, "Deleting an unnamed metadata queue.");
399 if (the_queue
->name
!= NULL
)
400 free(the_queue
->name
);
401 // debug(2, "destroying pc_queue_item_removed_signal");
402 pthread_cond_destroy(&the_queue
->pc_queue_item_removed_signal
);
403 // debug(2, "destroying pc_queue_item_added_signal");
404 pthread_cond_destroy(&the_queue
->pc_queue_item_added_signal
);
405 // debug(2, "destroying pc_queue_lock");
406 pthread_mutex_destroy(&the_queue
->pc_queue_lock
);
407 // debug(2, "destroying signals and locks done");
410 int send_metadata(uint32_t type
, uint32_t code
, char *data
, uint32_t length
, rtsp_message
*carrier
,
413 int send_ssnc_metadata(uint32_t code
, char *data
, uint32_t length
, int block
) {
414 return send_metadata('ssnc', code
, data
, length
, NULL
, block
);
417 void pc_queue_cleanup_handler(void *arg
) {
418 // debug(1, "pc_queue_cleanup_handler called.");
419 pc_queue
*the_queue
= (pc_queue
*)arg
;
420 int rc
= pthread_mutex_unlock(&the_queue
->pc_queue_lock
);
422 debug(1, "Error unlocking for pc_queue_add_item or pc_queue_get_item.");
425 int pc_queue_add_item(pc_queue
*the_queue
, const void *the_stuff
, int block
) {
430 rc
= debug_mutex_lock(&the_queue
->pc_queue_lock
, 10000, 2);
434 rc
= pthread_mutex_lock(&the_queue
->pc_queue_lock
);
436 debug(1, "Error locking for pc_queue_add_item");
437 pthread_cleanup_push(pc_queue_cleanup_handler
, (void *)the_queue
);
438 // leave this out if you want this to return if the queue is already full
439 // irrespective of the block flag.
441 while (the_queue->count == the_queue->capacity) {
442 rc = pthread_cond_wait(&the_queue->pc_queue_item_removed_signal,
443 &the_queue->pc_queue_lock); if (rc) debug(1, "Error waiting for item to be removed");
446 if (the_queue
->count
< the_queue
->capacity
) {
447 uint32_t i
= the_queue
->eoq
;
448 void *p
= the_queue
->items
+ the_queue
->item_size
* i
;
449 // void * p = &the_queue->qbase + the_queue->item_size*the_queue->eoq;
450 memcpy(p
, the_stuff
, the_queue
->item_size
);
452 // update the pointer
454 if (i
== the_queue
->capacity
)
455 // fold pointer if necessary
459 // debug(2,"metadata queue+ \"%s\" %d/%d.", the_queue->name, the_queue->count,
460 // the_queue->capacity);
461 if (the_queue
->count
== the_queue
->capacity
)
462 debug(3, "metadata queue \"%s\": is now full with %d items in it!", the_queue
->name
,
464 rc
= pthread_cond_signal(&the_queue
->pc_queue_item_added_signal
);
466 debug(1, "metadata queue \"%s\": error signalling after pc_queue_add_item",
469 response
= EWOULDBLOCK
; // a bit arbitrary, this.
471 "metadata queue \"%s\": is already full with %d items in it. Not adding this item to "
473 the_queue
->name
, the_queue
->count
);
475 pthread_cleanup_pop(1); // unlock the queue lock.
477 debug(1, "Adding an item to a NULL queue");
482 int pc_queue_get_item(pc_queue
*the_queue
, void *the_stuff
) {
485 rc
= pthread_mutex_lock(&the_queue
->pc_queue_lock
);
487 debug(1, "metadata queue \"%s\": error locking for pc_queue_get_item", the_queue
->name
);
488 pthread_cleanup_push(pc_queue_cleanup_handler
, (void *)the_queue
);
489 while (the_queue
->count
== 0) {
490 rc
= pthread_cond_wait(&the_queue
->pc_queue_item_added_signal
, &the_queue
->pc_queue_lock
);
492 debug(1, "metadata queue \"%s\": error waiting for item to be added", the_queue
->name
);
494 uint32_t i
= the_queue
->toq
;
495 // void * p = &the_queue->qbase + the_queue->item_size*the_queue->toq;
496 void *p
= the_queue
->items
+ the_queue
->item_size
* i
;
497 memcpy(the_stuff
, p
, the_queue
->item_size
);
499 // update the pointer
501 if (i
== the_queue
->capacity
)
502 // fold pointer if necessary
506 debug(3, "metadata queue- \"%s\" %d/%d.", the_queue
->name
, the_queue
->count
,
507 the_queue
->capacity
);
508 rc
= pthread_cond_signal(&the_queue
->pc_queue_item_removed_signal
);
510 debug(1, "metadata queue \"%s\": error signalling after pc_queue_get_item", the_queue
->name
);
511 pthread_cleanup_pop(1); // unlock the queue lock.
513 debug(1, "Removing an item from a NULL queue");
520 // note: connection numbers start at 1, so an except_this_one value of zero means "all threads"
521 void cancel_all_RTSP_threads(airplay_stream_c stream_category
, int except_this_one
) {
522 // if the stream category is unspecified_stream_category
523 // all categories are elegible for cancellation
524 // otherwise just the category itself
525 debug_mutex_lock(&conns_lock
, 1000000, 3);
527 for (i
= 0; i
< nconns
; i
++) {
528 if ((conns
[i
] != NULL
) && (conns
[i
]->running
!= 0) &&
529 (conns
[i
]->connection_number
!= except_this_one
) &&
530 ((stream_category
== unspecified_stream_category
) ||
531 (stream_category
== conns
[i
]->airplay_stream_category
))) {
532 pthread_cancel(conns
[i
]->thread
);
533 debug(1, "Connection %d: cancelled.", conns
[i
]->connection_number
);
534 } else if (conns
[i
] != NULL
) {
535 debug(1, "Connection %d: not cancelled.", conns
[i
]->connection_number
);
538 for (i
= 0; i
< nconns
; i
++) {
539 if ((conns
[i
] != NULL
) && (conns
[i
]->running
!= 0) &&
540 (conns
[i
]->connection_number
!= except_this_one
) &&
541 ((stream_category
== unspecified_stream_category
) ||
542 (stream_category
== conns
[i
]->airplay_stream_category
))) {
543 pthread_join(conns
[i
]->thread
, NULL
);
544 debug(1, "Connection %d: joined.", conns
[i
]->connection_number
);
549 debug_mutex_unlock(&conns_lock
, 3);
552 // The principal_conn variable points to the connection that
553 // controls the mDNS status and flags and that is potentially
554 // in control of the playing subsystem to output audio to a backend
555 // the principal_conn variable may be NULL
557 // the principal_conn is set by an ANNOUNCE message (Classic AirPlay) or
558 // by the initial SETUP (of a connection, not of a play session) message (AirPlay 2) and cleared
559 // when a session is terminated (AirPlay 2)
561 // In AirPlay 2, only one PTP connection can be live at any time, and it is the principal_conn.
562 // This is because, in AirPlay 2, the principal_conn connection
563 // also has control of the mDNS interface, and thus determines the state of the player as seen by
566 void release_play_lock(rtsp_conn_info
*conn
) {
567 pthread_cleanup_debug_mutex_lock(&principal_conn_lock
, 100000,
568 1); // don't let the principal_conn be changed
569 if (principal_conn
== conn
) { // if we have the player
571 debug(2, "Connection %d: principal_conn released.", conn
->connection_number
);
572 principal_conn
= NULL
; // let it go
574 pthread_cleanup_pop(1); // release the principal_conn lock
577 // stop the current principal_conn from playing if necessary and make conn the principal_conn.
579 int get_play_lock(rtsp_conn_info
*conn
, int allow_session_interruption
) {
581 pthread_cleanup_debug_mutex_lock(&principal_conn_lock
, 100000, 1);
582 if (principal_conn
!= NULL
)
583 debug(2, "Connection %d: is requested to relinquish principal_conn.",
584 principal_conn
->connection_number
);
586 debug(2, "Connection %d: request to acquire principal_conn.", conn
->connection_number
);
587 // returns -1 if it failed, 0 if it succeeded and 1 if it succeeded but
588 // interrupted an existing session
589 if (principal_conn
== NULL
) {
590 principal_conn
= conn
;
591 } else if (principal_conn
== conn
) {
593 warn("Connection %d: request to re-acquire principal_conn!",
594 principal_conn
->connection_number
);
595 } else if (allow_session_interruption
!= 0) {
596 player_stop(principal_conn
);
597 debug(2, "Connection %d: termination requested.", principal_conn
->connection_number
);
598 pthread_cancel(principal_conn
->thread
);
599 usleep(2000000); // don't know why this delay is needed.
600 principal_conn
= conn
; // make the conn the new principal_conn
601 response
= 1; // interrupted an existing session
603 response
= -1; // can't get it...
605 if (principal_conn
!= NULL
)
606 debug(3, "Connection %d has acquired principal_conn.", principal_conn
->connection_number
);
607 pthread_cleanup_pop(1); // release the principal_conn lock
611 void player_watchdog_thread_cleanup_handler(void *arg
) {
612 rtsp_conn_info
*conn
= (rtsp_conn_info
*)arg
;
613 debug(3, "Connection %d: Watchdog Exit.", conn
->connection_number
);
616 void *player_watchdog_thread_code(void *arg
) {
617 pthread_cleanup_push(player_watchdog_thread_cleanup_handler
, arg
);
618 rtsp_conn_info
*conn
= (rtsp_conn_info
*)arg
;
620 usleep(2000000); // check every two seconds
621 // debug(3, "Connection %d: Check the thread is doing something...", conn->connection_number);
622 #ifdef CONFIG_AIRPLAY_2
623 if ((config
.dont_check_timeout
== 0) && (config
.timeout
!= 0) && (conn
->airplay_type
== ap_1
)) {
625 if ((config
.dont_check_timeout
== 0) && (config
.timeout
!= 0)) {
627 debug_mutex_lock(&conn
->watchdog_mutex
, 1000, 0);
628 uint64_t last_watchdog_bark_time
= conn
->watchdog_bark_time
;
629 debug_mutex_unlock(&conn
->watchdog_mutex
, 0);
630 if (last_watchdog_bark_time
!= 0) {
631 uint64_t time_since_last_bark
=
632 (get_absolute_time_in_ns() - last_watchdog_bark_time
) / 1000000000;
633 uint64_t ct
= config
.timeout
; // go from int to 64-bit int
635 if (time_since_last_bark
>= ct
) {
636 conn
->watchdog_barks
++;
637 if (conn
->watchdog_barks
== 1) {
638 // debuglev = 3; // tell us everything.
640 "Connection %d: As Yeats almost said, \"Too long a silence / can make a stone "
642 conn
->connection_number
);
644 pthread_cancel(conn
->thread
);
645 } else if (conn
->watchdog_barks
== 3) {
646 if ((config
.cmd_unfixable
) && (config
.unfixable_error_reported
== 0)) {
647 config
.unfixable_error_reported
= 1;
648 command_execute(config
.cmd_unfixable
, "unable_to_cancel_play_session", 1);
650 die("an unrecoverable error, \"unable_to_cancel_play_session\", has been detected.",
651 conn
->connection_number
);
658 pthread_cleanup_pop(0); // should never happen
662 static void track_thread(rtsp_conn_info
*conn
) {
663 debug_mutex_lock(&conns_lock
, 1000000, 3);
664 // look for an empty slot first
667 while ((i
< nconns
) && (found
== 0)) {
668 if (conns
[i
] == NULL
)
676 // make space for a new element
677 conns
= realloc(conns
, sizeof(rtsp_conn_info
*) * (nconns
+ 1));
679 conns
[nconns
] = conn
;
682 die("could not reallocate memory for conns");
685 debug_mutex_unlock(&conns_lock
, 3);
688 int old_connection_count
= -1;
690 void cleanup_threads(void) {
694 int connection_count
= 0;
695 // debug(2, "culling threads.");
696 debug_mutex_lock(&conns_lock
, 1000000, 3);
697 for (i
= 0; i
< nconns
; i
++) {
698 if ((conns
[i
] != NULL
) && (conns
[i
]->running
== 0)) {
699 debug(2, "Found RTSP connection thread %d in a non-running state.",
700 conns
[i
]->connection_number
);
701 pthread_join(conns
[i
]->thread
, &retval
);
702 debug(2, "Connection %d: deleted in cleanup.", conns
[i
]->connection_number
);
706 if (conns
[i
] != NULL
) {
707 debug(2, "Airplay Volume for connection %d is %.6f.", conns
[i
]->connection_number
,
708 suggested_volume(conns
[i
]));
712 debug_mutex_unlock(&conns_lock
, 3);
714 if (old_connection_count
!= connection_count
) {
715 if (connection_count
== 0) {
716 debug(2, "No active connections.");
717 } else if (connection_count
== 1)
718 debug(2, "One active connection.");
720 debug(2, "%d active connections.", connection_count
);
721 old_connection_count
= connection_count
;
723 debug(2, "Airplay Volume for new connections is %.6f.", suggested_volume(NULL
));
726 // park a null at the line ending, and return the next line pointer
727 // accept \r, \n, or \r\n
728 static char *nextline(char *in
, int inbuf
) {
736 if ((*in
== '\n') && (inbuf
)) {
750 void msg_retain(rtsp_message
*msg
) {
751 int rc
= pthread_mutex_lock(&reference_counter_lock
);
753 debug(1, "Error %d locking reference counter lock");
754 if (msg
> (rtsp_message
*)0x00010000) {
755 msg
->referenceCount
++;
756 debug(3, "msg_free increment reference counter message %d to %d.", msg
->index_number
,
757 msg
->referenceCount
);
758 // debug(1,"msg_retain -- item %d reference count %d.", msg->index_number, msg->referenceCount);
759 rc
= pthread_mutex_unlock(&reference_counter_lock
);
761 debug(1, "Error %d unlocking reference counter lock");
763 debug(1, "invalid rtsp_message pointer 0x%x passed to retain", (uintptr_t)msg
);
767 rtsp_message
*msg_init(void) {
768 rtsp_message
*msg
= malloc(sizeof(rtsp_message
));
770 memset(msg
, 0, sizeof(rtsp_message
));
771 msg
->referenceCount
= 1; // from now on, any access to this must be protected with the lock
772 msg
->index_number
= msg_indexes
++;
773 debug(3, "msg_init message %d", msg
->index_number
);
775 die("msg_init -- can not allocate memory for rtsp_message %d.", msg_indexes
);
777 // debug(1,"msg_init -- create item %d.", msg->index_number);
781 int msg_add_header(rtsp_message
*msg
, char *name
, char *value
) {
782 if (msg
->nheaders
>= sizeof(msg
->name
) / sizeof(char *)) {
783 warn("too many headers?!");
787 msg
->name
[msg
->nheaders
] = strdup(name
);
788 msg
->value
[msg
->nheaders
] = strdup(value
);
794 char *msg_get_header(rtsp_message
*msg
, char *name
) {
796 for (i
= 0; i
< msg
->nheaders
; i
++)
797 if (!strcasecmp(msg
->name
[i
], name
))
798 return msg
->value
[i
];
802 void _debug_print_msg_headers(const char *filename
, const int linenumber
, int level
,
805 if (msg
->respcode
!= 0)
806 _debug(filename
, linenumber
, level
, " Response Code: %d.", msg
->respcode
);
807 for (i
= 0; i
< msg
->nheaders
; i
++) {
808 _debug(filename
, linenumber
, level
, " Type: \"%s\", content: \"%s\"", msg
->name
[i
],
814 static void debug_print_msg_content(int level, rtsp_message *msg) {
815 if (msg->contentlength) {
816 char *obf = malloc(msg->contentlength * 2 + 1);
820 for (obfc = 0; obfc < msg->contentlength; obfc++) {
821 snprintf(obfp, 3, "%02X", msg->content[obfc]);
825 debug(level, "Content (hex): \"%s\"", obf);
828 debug(level, "Can't allocate space for debug buffer");
831 debug(level, "No content");
836 void msg_free(rtsp_message
**msgh
) {
837 debug_mutex_lock(&reference_counter_lock
, 1000, 0);
838 if (*msgh
> (rtsp_message
*)0x00010000) {
839 rtsp_message
*msg
= *msgh
;
840 msg
->referenceCount
--;
841 if (msg
->referenceCount
)
842 debug(3, "msg_free decrement reference counter message %d to %d", msg
->index_number
,
843 msg
->referenceCount
);
844 if (msg
->referenceCount
== 0) {
846 for (i
= 0; i
< msg
->nheaders
; i
++) {
852 // debug(1,"msg_free item %d -- free.",msg->index_number);
853 uintptr_t index
= (msg
->index_number
) & 0xFFFF;
855 index
= 0x10000; // ensure it doesn't fold to zero.
857 (rtsp_message
*)(index
); // put a version of the index number of the freed message in here
858 debug(3, "msg_free freed message %d", msg
->index_number
);
861 // debug(1,"msg_free item %d -- decrement reference to
862 // %d.",msg->index_number,msg->referenceCount);
864 } else if (*msgh
!= NULL
) {
866 "msg_free: error attempting to free an allocated but already-freed rtsp_message, number "
870 debug_mutex_unlock(&reference_counter_lock
, 0);
873 int msg_handle_line(rtsp_message
**pmsg
, char *line
) {
874 rtsp_message
*msg
= *pmsg
;
880 sp
= NULL
; // this is to quieten a compiler warning
882 debug(3, "RTSP Message Received: \"%s\".", line
);
884 p
= strtok_r(line
, " ", &sp
);
887 strncpy(msg
->method
, p
, sizeof(msg
->method
) - 1);
889 p
= strtok_r(NULL
, " ", &sp
);
892 strncpy(msg
->path
, p
, sizeof(msg
->path
) - 1);
894 p
= strtok_r(NULL
, " ", &sp
);
897 if (strcmp(p
, "RTSP/1.0"))
905 p
= strstr(line
, ": ");
907 warn("bad header: >>%s<<", line
);
912 msg_add_header(msg
, line
, p
);
913 debug(3, " %s: %s.", line
, p
);
916 char *cl
= msg_get_header(msg
, "Content-Length");
924 debug(3, "msg_handle_line fail");
930 #ifdef CONFIG_AIRPLAY_2
932 void add_flush_request(int flushNow
, uint32_t flushFromSeq
, uint32_t flushFromTS
,
933 uint32_t flushUntilSeq
, uint32_t flushUntilTS
, rtsp_conn_info
*conn
) {
934 // immediate flush requests are added sequentially. Don't know how more than one could arise, TBH
935 flush_request_t
**t
= &conn
->flush_requests
;
938 flush_request_t
*u
= *t
;
939 if ((u
== NULL
) || ((u
->flushNow
== 0) && (flushNow
!= 0)) ||
940 (flushFromSeq
< u
->flushFromSeq
) ||
941 ((flushFromSeq
== u
->flushFromSeq
) && (flushFromTS
< u
->flushFromTS
))) {
942 flush_request_t
*n
= (flush_request_t
*)calloc(sizeof(flush_request_t
), 1);
943 n
->flushNow
= flushNow
;
944 n
->flushFromSeq
= flushFromSeq
;
945 n
->flushFromTS
= flushFromTS
;
946 n
->flushUntilSeq
= flushUntilSeq
;
947 n
->flushUntilTS
= flushUntilTS
;
957 void display_all_flush_requests(rtsp_conn_info
*conn
) {
958 if (conn
->flush_requests
== NULL
) {
959 debug(1, "No flush requests.");
961 flush_request_t
*t
= conn
->flush_requests
;
964 debug(1, "immediate flush to untilSeq: %u, untilTS: %u.", t
->flushUntilSeq
,
967 debug(1, "fromSeq: %u, fromTS: %u, to untilSeq: %u, untilTS: %u.", t
->flushFromSeq
,
968 t
->flushFromTS
, t
->flushUntilSeq
, t
->flushUntilTS
);
975 int rtsp_message_contains_plist(rtsp_message
*message
) {
976 int reply
= 0; // assume there is no plist in the message
977 if ((message
->contentlength
>= strlen("bplist00")) &&
978 (strstr(message
->content
, "bplist00") == message
->content
))
983 plist_t
plist_from_rtsp_content(rtsp_message
*message
) {
984 plist_t the_plist
= NULL
;
985 if (rtsp_message_contains_plist(message
)) {
986 plist_from_memory(message
->content
, message
->contentlength
, &the_plist
);
991 char *plist_content(plist_t the_plist
) {
992 // caller must free the returned character buffer
993 // convert it to xml format
995 char *plist_out
= NULL
;
996 plist_to_xml(the_plist
, &plist_out
, &size
);
998 // put it into a NUL-terminated string
999 char *reply
= malloc(size
+ 1);
1001 memcpy(reply
, plist_out
, size
);
1005 plist_free(the_plist
);
1011 // caller must free the returned character buffer
1012 char *rtsp_plist_content(rtsp_message
*message
) {
1014 // first, check if it has binary plist content
1015 if (rtsp_message_contains_plist(message
)) {
1016 // get the plist from the content
1018 plist_t the_plist
= plist_from_rtsp_content(message
);
1020 // convert it to xml format
1022 char *plist_out
= NULL
;
1023 plist_to_xml(the_plist
, &plist_out
, &size
);
1025 // put it into a NUL-terminated string
1026 reply
= malloc(size
+ 1);
1028 memcpy(reply
, plist_out
, size
);
1032 plist_free(the_plist
);
1041 void _debug_log_rtsp_message(const char *filename
, const int linenumber
, int level
, char *prompt
,
1042 rtsp_message
*message
) {
1043 if (level
> debuglev
)
1045 if ((prompt
) && (*prompt
!= '\0')) // okay to pass NULL or an empty list...
1046 _debug(filename
, linenumber
, level
, prompt
);
1047 _debug_print_msg_headers(filename
, linenumber
, level
, message
);
1048 #ifdef CONFIG_AIRPLAY_2
1049 char *plist_content
= rtsp_plist_content(message
);
1050 if (plist_content
) {
1051 _debug(filename
, linenumber
, level
, " Content Plist (as XML):\n--\n%s--", plist_content
);
1052 free(plist_content
);
1056 _debug(filename
, linenumber
, level
, " No Content Plist. Content length: %d.",
1057 message
->contentlength
);
1061 #define debug_log_rtsp_message(level, prompt, message) \
1062 _debug_log_rtsp_message(__FILE__, __LINE__, level, prompt, message)
1063 #define debug_print_msg_headers(level, message) \
1064 _debug_print_msg_headers(__FILE__, __LINE__, level, message)
1066 #ifdef CONFIG_AIRPLAY_2
1067 static void buf_add(sized_buffer
*buf
, uint8_t *in
, size_t in_len
) {
1068 if (buf
->length
+ in_len
> buf
->size
) {
1069 buf
->size
= buf
->length
+ in_len
+ 2048; // Extra legroom to avoid future memcpy's
1070 uint8_t *new = malloc(buf
->size
);
1071 memcpy(new, buf
->data
, buf
->length
);
1075 memcpy(buf
->data
+ buf
->length
, in
, in_len
);
1076 buf
->length
+= in_len
;
1079 static void buf_drain(sized_buffer
*buf
, ssize_t len
) {
1080 if (len
< 0 || (size_t)len
>= buf
->length
) {
1082 memset(buf
, 0, sizeof(sized_buffer
));
1085 memmove(buf
->data
, buf
->data
+ len
, buf
->length
- len
);
1089 static size_t buf_remove(sized_buffer
*buf
, uint8_t *out
, size_t out_len
) {
1090 size_t bytes
= (buf
->length
> out_len
) ? out_len
: buf
->length
;
1091 memcpy(out
, buf
->data
, bytes
);
1092 buf_drain(buf
, bytes
);
1096 static ssize_t
read_encrypted(int fd
, pair_cipher_bundle
*ctx
, void *buf
, size_t count
) {
1101 // If there is leftover decoded content from the last pass just return that
1102 if (ctx
->plaintext_read_buffer
.length
> 0) {
1103 return buf_remove(&ctx
->plaintext_read_buffer
, buf
, count
);
1107 ssize_t got
= read(fd
, in
, sizeof(in
));
1110 buf_add(&ctx
->encrypted_read_buffer
, in
, got
);
1112 ssize_t consumed
= pair_decrypt(&plain
, &plain_len
, ctx
->encrypted_read_buffer
.data
,
1113 ctx
->encrypted_read_buffer
.length
, ctx
->cipher_ctx
);
1116 buf_drain(&ctx
->encrypted_read_buffer
, consumed
);
1117 } while (plain_len
== 0);
1119 // Fast path, avoids some memcpy + allocs in case of the normal, small message
1120 /* if (ctx->plaintext_read_buffer.len == 0 && plain_len < count) {
1121 memcpy(buf, plain, plain_len);
1126 buf_add(&ctx
->plaintext_read_buffer
, plain
, plain_len
);
1129 return buf_remove(&ctx
->plaintext_read_buffer
, buf
, count
);
1132 static ssize_t
write_encrypted(int fd
, pair_cipher_bundle
*ctx
, const void *buf
, size_t count
) {
1134 size_t encrypted_len
;
1136 ssize_t ret
= pair_encrypt(&encrypted
, &encrypted_len
, buf
, count
, ctx
->cipher_ctx
);
1138 debug(1, pair_cipher_errmsg(ctx
->cipher_ctx
));
1142 size_t remain
= encrypted_len
;
1143 while (remain
> 0) {
1144 ssize_t wrote
= write(fd
, encrypted
+ (encrypted_len
- remain
), remain
);
1156 static ssize_t write_encrypted(rtsp_conn_info *conn, const void *buf, size_t count) {
1158 size_t encrypted_len;
1161 pair_encrypt(&encrypted, &encrypted_len, buf, count, conn->ap2_pairing_context.cipher_ctx);
1163 debug(1, pair_cipher_errmsg(conn->ap2_pairing_context.cipher_ctx));
1167 size_t remain = encrypted_len;
1168 while (remain > 0) {
1169 ssize_t wrote = write(conn->fd, encrypted + (encrypted_len - remain), remain);
1182 ssize_t
timed_read_from_rtsp_connection(rtsp_conn_info
*conn
, uint64_t wait_time
, void *buf
,
1184 // note: a wait time of zero means wait forever
1185 ssize_t result
= 0; // closed
1187 int64_t remaining_time
= 0;
1188 uint64_t time_to_wait_to
= get_absolute_time_in_ns();
1190 time_to_wait_to
= time_to_wait_to
+ wait_time
;
1193 if (setsockopt(conn
->fd
, SOL_SOCKET
, SO_KEEPALIVE
, (void *)&flags
, sizeof(flags
))) {
1194 debug(1, "can't enable keepalive checking on the RTSP socket");
1197 // remaining_time will be zero if wait_time is zero
1198 if (wait_time
!= 0) {
1199 remaining_time
= time_to_wait_to
- get_absolute_time_in_ns();
1203 tv
.tv_sec
= remaining_time
/ 1000000000; // seconds
1204 tv
.tv_usec
= (remaining_time
% 1000000000) / 1000; // microseconds
1205 if (setsockopt(conn
->fd
, SOL_SOCKET
, SO_RCVTIMEO
, (const char *)&tv
, sizeof tv
) != 0) {
1206 char errorstring
[1024];
1207 strerror_r(errno
, (char *)errorstring
, sizeof(errorstring
));
1208 debug(1, "could not set time limit on timed_read_from_rtsp_connection -- error %d \"%s\".",
1209 errno
, errorstring
);
1212 #ifdef CONFIG_AIRPLAY_2
1213 if (conn
->ap2_pairing_context
.control_cipher_bundle
.cipher_ctx
) {
1214 conn
->ap2_pairing_context
.control_cipher_bundle
.is_encrypted
= 1;
1216 read_encrypted(conn
->fd
, &conn
->ap2_pairing_context
.control_cipher_bundle
, buf
, count
);
1218 result
= read(conn
->fd
, buf
, count
);
1221 result
= read(conn
->fd
, buf
, count
);
1224 remaining_time
= time_to_wait_to
- get_absolute_time_in_ns();
1225 if (((result
== -1) && ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
))) && (remaining_time
> 0))
1226 debug(1, "remaining time on a timed read is %" PRId64
" ns.", remaining_time
);
1227 } while (((result
== -1) && ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
))) &&
1228 (remaining_time
> 0));
1231 debug(1, "Connection %d: attempt to read from a closed RTSP connection.",
1232 conn
->connection_number
);
1237 #ifdef CONFIG_AIRPLAY_2
1238 void set_client_as_ptp_clock(rtsp_conn_info
*conn
) {
1239 char timing_list_message
[4096] = "";
1240 strncat(timing_list_message
, "T ", sizeof(timing_list_message
) - 1 - strlen(timing_list_message
));
1241 strncat(timing_list_message
, (const char *)&conn
->client_ip_string
,
1242 sizeof(timing_list_message
) - 1 - strlen(timing_list_message
));
1243 ptp_send_control_message_string(timing_list_message
);
1246 void clear_ptp_clock() { ptp_send_control_message_string("T"); }
1249 ssize_t
read_from_rtsp_connection(rtsp_conn_info
*conn
, void *buf
, size_t count
) {
1250 // first try to read with a timeout, to see if there is any traffic...
1251 // ssize_t response = timed_read_from_rtsp_connection(conn, 20000000000L, buf, count);
1252 // actually don't use a timeout -- OwnTone doesn't supply regular traffic.
1253 ssize_t response
= timed_read_from_rtsp_connection(conn
, 0, buf
, count
);
1254 if ((response
== -1) && ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
))) {
1255 if (conn
->rtsp_link_is_idle
== 0) {
1256 debug(1, "Connection %d: RTSP connection is idle.", conn
->connection_number
);
1257 conn
->rtsp_link_is_idle
= 1;
1258 conn
->udp_clock_sender_is_initialised
= 0;
1259 conn
->udp_clock_is_initialised
= 0;
1261 response
= timed_read_from_rtsp_connection(conn
, 0, buf
, count
);
1263 if (conn
->rtsp_link_is_idle
== 1) {
1264 conn
->rtsp_link_is_idle
= 0;
1265 debug(1, "Connection %d: RTSP connection traffic has resumed.", conn
->connection_number
);
1266 #ifdef CONFIG_AIRPLAY_2
1267 if (conn
->airplay_stream_type
== realtime_stream
) {
1268 conn
->last_anchor_info_is_valid
= 0;
1269 conn
->anchor_remote_info_is_valid
= 0;
1270 conn
->first_packet_timestamp
= 0;
1271 conn
->input_frame_rate_starting_point_is_valid
= 0;
1275 conn
->anchor_remote_info_is_valid
= 0;
1276 conn
->local_to_remote_time_difference_measurement_time
= 0;
1277 conn
->local_to_remote_time_difference
= 0;
1278 conn
->first_packet_timestamp
= 0;
1279 conn
->input_frame_rate_starting_point_is_valid
= 0;
1286 enum rtsp_read_request_response
rtsp_read_request(rtsp_conn_info
*conn
, rtsp_message
**the_packet
) {
1288 *the_packet
= NULL
; // need this for error handling
1290 enum rtsp_read_request_response reply
= rtsp_read_request_response_ok
;
1291 ssize_t buflen
= 4096;
1292 #ifdef CONFIG_METADATA
1293 if ((config
.metadata_enabled
!= 0) && (config
.get_coverart
!= 0))
1294 buflen
= 1024 * 256; // big enough for typical picture data, which will be base64 encoded
1296 int release_buffer
= 0; // on exit, don't deallocate the buffer if everything was okay
1297 char *buf
= malloc(buflen
+ 1); // add a NUL at the end
1299 warn("Connection %d: rtsp_read_request: can't get a buffer.", conn
->connection_number
);
1300 return (rtsp_read_request_response_error
);
1302 pthread_cleanup_push(malloc_cleanup
, buf
);
1307 while (msg_size
< 0) {
1310 if (conn->stop != 0) {
1311 debug(3, "Connection %d: Shutdown requested by client.", conn->connection_number);
1312 reply = rtsp_read_request_response_immediate_shutdown_requested;
1317 nread
= read_from_rtsp_connection(conn
, buf
+ inbuf
, buflen
- inbuf
);
1320 // a blocking read that returns zero means eof -- implies connection closed by client
1321 debug(3, "Connection %d: Connection closed by client.", conn
->connection_number
);
1322 reply
= rtsp_read_request_response_channel_closed
;
1323 // Note: the socket will be closed when the thread exits
1327 // An ETIMEDOUT error usually means keepalive has failed.
1332 if (errno
== EAGAIN
) {
1333 debug(1, "Connection %d: getting Error 11 -- EAGAIN from a blocking read!",
1334 conn
->connection_number
);
1337 if (errno
== ETIMEDOUT
) {
1338 debug(1, "Connection %d: ETIMEDOUT -- keepalive timeout.", conn
->connection_number
);
1339 reply
= rtsp_read_request_response_channel_closed
;
1340 // Note: the socket will be closed when the thread exits
1343 if (errno
!= ECONNRESET
) {
1344 char errorstring
[1024];
1345 strerror_r(errno
, (char *)errorstring
, sizeof(errorstring
));
1347 debug(2, "Connection %d: rtsp_read_request_response_read_error %d: \"%s\".",
1348 conn
->connection_number
, errno
, (char *)errorstring
);
1350 reply
= rtsp_read_request_response_read_error
;
1354 /* // this outputs the message received
1356 void *pt = malloc(nread+1);
1357 memset(pt, 0, nread+1);
1358 memcpy(pt, buf + inbuf, nread);
1359 debug(1, "Incoming string on port: \"%s\"",pt);
1367 while (msg_size
< 0 && (next
= nextline(buf
, inbuf
))) {
1368 msg_size
= msg_handle_line(the_packet
, buf
);
1370 if (!(*the_packet
)) {
1371 debug(1, "Connection %d: rtsp_read_request can't find an RTSP header.",
1372 conn
->connection_number
);
1373 reply
= rtsp_read_request_response_bad_packet
;
1377 inbuf
-= next
- buf
;
1379 memmove(buf
, next
, inbuf
);
1383 if (msg_size
> buflen
) {
1384 buf
= realloc(buf
, msg_size
+ 1);
1386 warn("Connection %d: too much content.", conn
->connection_number
);
1387 reply
= rtsp_read_request_response_error
;
1393 uint64_t threshold_time
=
1394 get_absolute_time_in_ns() + ((uint64_t)15000000000); // i.e. fifteen seconds from now
1395 int warning_message_sent
= 0;
1397 // const size_t max_read_chunk = 1024 * 1024 / 16;
1398 while (inbuf
< msg_size
) {
1400 // we are going to read the stream in chunks and time how long it takes to
1402 // If it's taking too long, (and we find out about it), we will send an
1406 if (warning_message_sent
== 0) {
1407 uint64_t time_now
= get_absolute_time_in_ns();
1408 if (time_now
> threshold_time
) { // it's taking too long
1409 debug(1, "Error receiving metadata from source -- transmission seems "
1411 #ifdef CONFIG_METADATA
1412 send_ssnc_metadata('stal', NULL
, 0, 1);
1414 warning_message_sent
= 1;
1419 if (conn->stop != 0) {
1420 debug(1, "RTSP shutdown requested.");
1421 reply = rtsp_read_request_response_immediate_shutdown_requested;
1426 size_t read_chunk
= msg_size
- inbuf
;
1427 // if (read_chunk > max_read_chunk)
1428 // read_chunk = max_read_chunk;
1429 // usleep(80000); // wait about 80 milliseconds between reads of up to max_read_chunk
1430 nread
= read_from_rtsp_connection(conn
, buf
+ inbuf
, read_chunk
);
1432 reply
= rtsp_read_request_response_error
;
1438 if (errno
== EAGAIN
) {
1439 debug(1, "Getting Error 11 -- EAGAIN from a blocking read!");
1442 if (errno
!= ECONNRESET
) {
1443 char errorstring
[1024];
1444 strerror_r(errno
, (char *)errorstring
, sizeof(errorstring
));
1445 debug(1, "Connection %d: rtsp_read_request_response_read_error %d: \"%s\".",
1446 conn
->connection_number
, errno
, (char *)errorstring
);
1448 reply
= rtsp_read_request_response_read_error
;
1454 rtsp_message
*msg
= *the_packet
;
1455 msg
->contentlength
= inbuf
;
1457 char *jp
= inbuf
+ buf
;
1461 if (reply
!= rtsp_read_request_response_ok
) {
1462 msg_free(the_packet
);
1463 release_buffer
= 1; // allow the buffer to be released
1465 pthread_cleanup_pop(release_buffer
);
1469 int msg_write_response(rtsp_conn_info
*conn
, rtsp_message
*resp
) {
1471 int pktfree
= sizeof(pkt
);
1481 struct response_t responses
[] = {{200, "OK"},
1482 {400, "Bad Request"},
1483 {403, "Unauthorized"},
1485 {451, "Unavailable"},
1486 {456, "Header Field Not Valid for Resource"},
1487 {470, "Connection Authorization Required"},
1488 {500, "Internal Server Error"},
1489 {501, "Not Implemented"}};
1490 // 451 is really "Unavailable For Legal Reasons"!
1492 char *respcode_text
= "Unauthorized";
1493 for (i
= 0; i
< sizeof(responses
) / sizeof(struct response_t
); i
++) {
1494 if (resp
->respcode
== responses
[i
].code
) {
1496 respcode_text
= responses
[i
].string
;
1501 debug(1, "can't find text for response code %d. Using \"%s\" instead.", resp
->respcode
,
1504 n
= snprintf(p
, pktfree
, "RTSP/1.0 %d %s\r\n", resp
->respcode
, respcode_text
);
1508 for (i
= 0; i
< resp
->nheaders
; i
++) {
1509 // debug(3, " %s: %s.", resp->name[i], resp->value[i]);
1510 n
= snprintf(p
, pktfree
, "%s: %s\r\n", resp
->name
[i
], resp
->value
[i
]);
1513 if (pktfree
<= 1024) {
1514 debug(1, "Attempted to write overlong RTSP packet 1");
1519 // Here, if there's content, write the Content-Length header ...
1521 if (resp
->contentlength
) {
1522 debug(2, "Responding with content of length %d", resp
->contentlength
);
1523 n
= snprintf(p
, pktfree
, "Content-Length: %d\r\n", resp
->contentlength
);
1526 if (pktfree
<= 1024) {
1527 debug(1, "Attempted to write overlong RTSP packet 2");
1532 n
= snprintf(p
, pktfree
, "\r\n");
1536 if (resp
->contentlength
) {
1537 memcpy(p
, resp
->content
, resp
->contentlength
);
1538 pktfree
-= resp
->contentlength
;
1539 p
+= resp
->contentlength
;
1542 if (pktfree
<= 1024) {
1543 debug(1, "Attempted to write overlong RTSP packet 3");
1547 // here, if the link is encrypted, better do it
1549 #ifdef CONFIG_AIRPLAY_2
1551 if (conn
->ap2_pairing_context
.control_cipher_bundle
.is_encrypted
) {
1553 write_encrypted(conn
->fd
, &conn
->ap2_pairing_context
.control_cipher_bundle
, pkt
, p
- pkt
);
1555 reply
= write(conn
->fd
, pkt
, p
- pkt
);
1558 ssize_t reply
= write(conn
->fd
, pkt
, p
- pkt
);
1562 char errorstring
[1024];
1563 strerror_r(errno
, (char *)errorstring
, sizeof(errorstring
));
1564 debug(1, "msg_write_response error %d: \"%s\".", errno
, (char *)errorstring
);
1567 if (reply
!= p
- pkt
) {
1568 debug(1, "msg_write_response error -- requested bytes: %d not fully written: %d.", p
- pkt
,
1575 char *get_category_string(airplay_stream_c cat
) {
1578 case unspecified_stream_category
:
1579 category
= "unspecified stream";
1582 category
= "PTP stream";
1585 category
= "NTP stream";
1587 case remote_control_stream
:
1588 category
= "Remote Control stream";
1590 case classic_airplay_stream
:
1591 category
= "Classic AirPlay stream";
1594 category
= "Unexpected stream code";
1600 void handle_record_2(rtsp_conn_info
*conn
, __attribute((unused
)) rtsp_message
*req
,
1601 rtsp_message
*resp
) {
1602 debug(2, "Connection %d: RECORD on %s", conn
->connection_number
,
1603 get_category_string(conn
->airplay_stream_category
));
1604 // debug_log_rtsp_message(1, "RECORD incoming message", req);
1605 resp
->respcode
= 200;
1608 void handle_record(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
1609 debug(2, "Connection %d: RECORD", conn
->connection_number
);
1610 if ((conn
!= NULL
) && (principal_conn
== conn
)) {
1611 // if (have_play_lock(conn)) {
1612 if (conn
->player_thread
)
1613 warn("Connection %d: RECORD: Duplicate RECORD message -- ignored", conn
->connection_number
);
1615 debug(2, "Connection %d: Classic AirPlay connection from %s:%u to self at %s:%u.",
1616 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
1617 conn
->self_ip_string
, conn
->self_rtsp_port
);
1618 activity_monitor_signify_activity(1);
1619 player_prepare_to_play(conn
);
1620 player_play(conn
); // the thread better be 0
1623 resp
->respcode
= 200;
1624 // I think this is for telling the client what the absolute minimum latency
1626 // and when the client specifies a latency, it should be added to this figure.
1628 // Thus, [the old version of] AirPlay's latency figure of 77175, when added to 11025 gives you
1630 // and iTunes' latency figure of 88553, when added to 11025 gives you 99578,
1631 // pretty close to the 99400 we guessed.
1633 msg_add_header(resp
, "Audio-Latency", "11025");
1636 uint32_t rtptime
= 0;
1637 char *hdr
= msg_get_header(req
, "RTP-Info");
1640 // debug(1,"FLUSH message received: \"%s\".",hdr);
1641 // get the rtp timestamp
1642 p
= strstr(hdr
, "rtptime=");
1646 rtptime
= uatoi(p
+ 1); // unsigned integer -- up to 2^32-1
1648 // debug(1,"RTSP Flush Requested by handle_record: %u.",rtptime);
1649 player_flush(rtptime
, conn
);
1654 warn("Connection %d RECORD received without having the player (no ANNOUNCE?)",
1655 conn
->connection_number
);
1656 resp
->respcode
= 451;
1660 #ifdef CONFIG_AIRPLAY_2
1662 void handle_get_info(__attribute((unused
)) rtsp_conn_info
*conn
, rtsp_message
*req
,
1663 rtsp_message
*resp
) {
1664 debug_log_rtsp_message(2, "GET /info:", req
);
1665 if (rtsp_message_contains_plist(req
)) { // it's stage one
1666 // get version of AirPlay -- it might be too old. Not using it yet.
1667 char *hdr
= msg_get_header(req
, "User-Agent");
1669 if (strstr(hdr
, "AirPlay/") == hdr
) {
1670 hdr
= hdr
+ strlen("AirPlay/");
1671 // double airplay_version = 0.0;
1672 // airplay_version = atof(hdr);
1673 debug(2, "Connection %d: GET_INFO: Source AirPlay Version is: %s.", conn
->connection_number
,
1677 plist_t info_plist
= NULL
;
1678 plist_from_memory(req
->content
, req
->contentlength
, &info_plist
);
1680 plist_t qualifier
= plist_dict_get_item(info_plist
, "qualifier");
1681 if (qualifier
== NULL
) {
1682 debug(1, "GET /info Stage 1: plist->qualifier was NULL");
1685 if (plist_array_get_size(qualifier
) < 1) {
1686 debug(1, "GET /info Stage 1: plist->qualifier array length < 1");
1689 plist_t qualifier_array_value
= plist_array_get_item(qualifier
, 0);
1690 char *qualifier_array_val_cstr
;
1691 plist_get_string_val(qualifier_array_value
, &qualifier_array_val_cstr
);
1692 if (qualifier_array_val_cstr
== NULL
) {
1693 debug(1, "GET /info Stage 1: first item in qualifier array not a string");
1696 debug(2, "GET /info Stage 1: qualifier: %s", qualifier_array_val_cstr
);
1697 plist_free(info_plist
);
1698 free(qualifier_array_val_cstr
);
1700 // uint8_t bt_addr[6] = {0xB8, 0x27, 0xEB, 0xB7, 0xD4, 0x0E};
1701 plist_t response_plist
= NULL
;
1702 plist_from_xml((const char *)plists_get_info_response_xml
, plists_get_info_response_xml_len
,
1704 if (response_plist
== NULL
) {
1705 debug(1, "GET /info Stage 1: response plist not created from XML!");
1707 void *qualifier_response_data
= NULL
;
1708 size_t qualifier_response_data_length
= 0;
1709 if (add_pstring_to_malloc("acl=0", &qualifier_response_data
,
1710 &qualifier_response_data_length
) == 0)
1711 debug(1, "Problem");
1712 if (add_pstring_to_malloc(deviceIdString
, &qualifier_response_data
,
1713 &qualifier_response_data_length
) == 0)
1714 debug(1, "Problem");
1715 if (add_pstring_to_malloc(featuresString
, &qualifier_response_data
,
1716 &qualifier_response_data_length
) == 0)
1717 debug(1, "Problem");
1718 if (add_pstring_to_malloc("rsf=0x0", &qualifier_response_data
,
1719 &qualifier_response_data_length
) == 0)
1720 debug(1, "Problem");
1721 if (add_pstring_to_malloc("flags=0x4", &qualifier_response_data
,
1722 &qualifier_response_data_length
) == 0)
1723 debug(1, "Problem");
1724 if (add_pstring_to_malloc("model=Shairport Sync", &qualifier_response_data
,
1725 &qualifier_response_data_length
) == 0)
1726 debug(1, "Problem");
1727 if (add_pstring_to_malloc("manufacturer=", &qualifier_response_data
,
1728 &qualifier_response_data_length
) == 0)
1729 debug(1, "Problem");
1730 if (add_pstring_to_malloc("serialNumber=", &qualifier_response_data
,
1731 &qualifier_response_data_length
) == 0)
1732 debug(1, "Problem");
1733 if (add_pstring_to_malloc("protovers=1.1", &qualifier_response_data
,
1734 &qualifier_response_data_length
) == 0)
1735 debug(1, "Problem");
1736 if (add_pstring_to_malloc("srcvers=366.0", &qualifier_response_data
,
1737 &qualifier_response_data_length
) == 0)
1738 debug(1, "Problem");
1739 if (add_pstring_to_malloc(piString
, &qualifier_response_data
,
1740 &qualifier_response_data_length
) == 0)
1741 debug(1, "Problem");
1742 if (add_pstring_to_malloc(gidString
, &qualifier_response_data
,
1743 &qualifier_response_data_length
) == 0)
1744 debug(1, "Problem");
1745 if (add_pstring_to_malloc("gcgl=0", &qualifier_response_data
,
1746 &qualifier_response_data_length
) == 0)
1747 debug(1, "Problem");
1748 snprintf(pkString
, sizeof(pkString
), "pk=");
1749 pkString_make(pkString
+ strlen("pk="), sizeof(pkString
) - strlen("pk="),
1750 config
.airplay_device_id
);
1751 if (add_pstring_to_malloc(pkString
, &qualifier_response_data
,
1752 &qualifier_response_data_length
) == 0)
1753 debug(1, "Problem");
1754 // debug(1,"qualifier_response_data_length: %u.", qualifier_response_data_length);
1756 plist_dict_set_item(response_plist
, "txtAirPlay",
1757 plist_new_data(qualifier_response_data
, qualifier_response_data_length
));
1759 plist_dict_set_item(response_plist
, "features", plist_new_uint(config
.airplay_features
));
1760 plist_dict_set_item(response_plist
, "statusFlags",
1761 plist_new_uint(config
.airplay_statusflags
));
1762 plist_dict_set_item(response_plist
, "deviceID", plist_new_string(config
.airplay_device_id
));
1763 plist_dict_set_item(response_plist
, "pi", plist_new_string(config
.airplay_pi
));
1764 plist_dict_set_item(response_plist
, "name", plist_new_string(config
.service_name
));
1765 char *vs
= get_version_string();
1766 // plist_dict_set_item(response_plist, "model", plist_new_string(vs));
1767 plist_dict_set_item(response_plist
, "model", plist_new_string("Shairport Sync"));
1769 // pkString_make(pkString, sizeof(pkString), config.airplay_device_id);
1770 // plist_dict_set_item(response_plist, "pk", plist_new_string(pkString));
1771 plist_to_bin(response_plist
, &resp
->content
, &resp
->contentlength
);
1772 if (resp
->contentlength
== 0)
1773 debug(1, "GET /info Stage 1: response bplist not created!");
1774 plist_free(response_plist
);
1775 free(qualifier_response_data
);
1777 msg_add_header(resp
, "Content-Type", "application/x-apple-binary-plist");
1778 debug_log_rtsp_message(2, "GET /info Stage 1 Response:", resp
);
1779 resp
->respcode
= 200;
1783 resp
->respcode
= 400;
1785 } else { // stage two
1786 plist_t response_plist
= NULL
;
1787 plist_from_xml((const char *)plists_get_info_response_xml
, plists_get_info_response_xml_len
,
1789 plist_dict_set_item(response_plist
, "features", plist_new_uint(config
.airplay_features
));
1790 plist_dict_set_item(response_plist
, "statusFlags", plist_new_uint(config
.airplay_statusflags
));
1791 plist_dict_set_item(response_plist
, "deviceID", plist_new_string(config
.airplay_device_id
));
1792 plist_dict_set_item(response_plist
, "pi", plist_new_string(config
.airplay_pi
));
1793 plist_dict_set_item(response_plist
, "name", plist_new_string(config
.service_name
));
1794 char *vs
= get_version_string();
1795 // plist_dict_set_item(response_plist, "model", plist_new_string(vs));
1796 plist_dict_set_item(response_plist
, "model", plist_new_string("Shairport Sync"));
1798 // pkString_make(pkString, sizeof(pkString), config.airplay_device_id);
1799 // plist_dict_set_item(response_plist, "pk", plist_new_string(pkString));
1800 plist_to_bin(response_plist
, &resp
->content
, &resp
->contentlength
);
1801 plist_free(response_plist
);
1802 msg_add_header(resp
, "Content-Type", "application/x-apple-binary-plist");
1803 debug_log_rtsp_message(2, "GET /info Stage 2 Response", resp
);
1804 resp
->respcode
= 200;
1809 void handle_flushbuffered(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
1810 debug(3, "Connection %d: FLUSHBUFFERED %s : Content-Length %d", conn
->connection_number
,
1811 req
->path
, req
->contentlength
);
1812 debug_log_rtsp_message(2, "FLUSHBUFFERED request", req
);
1814 uint64_t flushFromSeq
= 0;
1815 uint64_t flushFromTS
= 0;
1816 uint64_t flushUntilSeq
= 0;
1817 uint64_t flushUntilTS
= 0;
1818 int flushFromValid
= 0;
1819 plist_t messagePlist
= plist_from_rtsp_content(req
);
1820 if (messagePlist
!= NULL
) {
1821 plist_t item
= plist_dict_get_item(messagePlist
, "flushFromSeq");
1823 debug(2, "Can't find a flushFromSeq");
1826 plist_get_uint_val(item
, &flushFromSeq
);
1827 debug(2, "flushFromSeq is %" PRId64
".", flushFromSeq
);
1830 item
= plist_dict_get_item(messagePlist
, "flushFromTS");
1832 if (flushFromValid
!= 0)
1833 debug(1, "flushFromSeq without flushFromTS!");
1835 debug(2, "Can't find a flushFromTS");
1837 plist_get_uint_val(item
, &flushFromTS
);
1838 if (flushFromValid
== 0)
1839 debug(1, "flushFromTS without flushFromSeq!");
1840 debug(2, "flushFromTS is %" PRId64
".", flushFromTS
);
1843 item
= plist_dict_get_item(messagePlist
, "flushUntilSeq");
1845 debug(1, "Can't find the flushUntilSeq");
1847 plist_get_uint_val(item
, &flushUntilSeq
);
1848 debug(2, "flushUntilSeq is %" PRId64
".", flushUntilSeq
);
1851 item
= plist_dict_get_item(messagePlist
, "flushUntilTS");
1853 debug(1, "Can't find the flushUntilTS");
1855 plist_get_uint_val(item
, &flushUntilTS
);
1856 debug(2, "flushUntilTS is %" PRId64
".", flushUntilTS
);
1859 debug_mutex_lock(&conn
->flush_mutex
, 1000, 1);
1860 // a flush with from... components will not be followed by a setanchor (i.e. a play)
1861 // if it's a flush that will be followed by a setanchor (i.e. a play) then stop play now.
1862 if (flushFromValid
== 0)
1863 conn
->ap2_play_enabled
= 0;
1865 // add the exact request as made to the linked list (not used for anything but diagnostics now)
1866 // int flushNow = 0;
1867 // if (flushFromValid == 0)
1869 // add_flush_request(flushNow, flushFromSeq, flushFromTS, flushUntilSeq, flushUntilTS, conn);
1871 // now, if it's an immediate flush, replace the existing request, if any
1872 // but it if's a deferred flush and there is an existing deferred request,
1873 // only update the flushUntil stuff -- that seems to preserve
1874 // the intended semantics
1876 // so, always replace these
1877 conn
->ap2_flush_until_sequence_number
= flushUntilSeq
;
1878 conn
->ap2_flush_until_rtp_timestamp
= flushUntilTS
;
1880 if ((conn
->ap2_flush_requested
!= 0) && (conn
->ap2_flush_from_valid
!= 0) &&
1881 (flushFromValid
!= 0)) {
1882 // if there is a request already, and it's a deferred request, and the current request is also
1883 // deferred... do nothing! -- leave the starting point in place. Yeah, yeah, we know de
1884 // Morgan's Law, but this seems clearer
1886 conn
->ap2_flush_from_sequence_number
= flushFromSeq
;
1887 conn
->ap2_flush_from_rtp_timestamp
= flushFromTS
;
1890 conn
->ap2_flush_from_valid
= flushFromValid
;
1891 conn
->ap2_flush_requested
= 1;
1893 // reflect the possibly updated flush request
1894 // add_flush_request(flushNow, conn->ap2_flush_from_sequence_number,
1895 // conn->ap2_flush_from_rtp_timestamp, conn->ap2_flush_until_sequence_number,
1896 // conn->ap2_flush_until_rtp_timestamp, conn);
1898 debug_mutex_unlock(&conn
->flush_mutex
, 3);
1901 debug(2, "Deferred Flush Requested");
1903 debug(2, "Immediate Flush Requested");
1905 plist_free(messagePlist
);
1906 // display_all_flush_requests(conn);
1909 resp
->respcode
= 200;
1912 void handle_setrate(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
1913 debug(3, "Connection %d: SETRATE %s : Content-Length %d", conn
->connection_number
, req
->path
,
1914 req
->contentlength
);
1915 debug_log_rtsp_message(2, "SETRATE request -- unimplemented", req
);
1916 resp
->respcode
= 501; // Not Implemented
1919 void handle_unimplemented_ap1(__attribute((unused
)) rtsp_conn_info
*conn
, rtsp_message
*req
,
1920 rtsp_message
*resp
) {
1921 debug_log_rtsp_message(1, "request not recognised for AirPlay 1 operation", req
);
1922 resp
->respcode
= 501;
1925 void handle_setrateanchori(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
1926 debug(3, "Connection %d: SETRATEANCHORI %s :: Content-Length %d", conn
->connection_number
,
1927 req
->path
, req
->contentlength
);
1929 plist_t messagePlist
= plist_from_rtsp_content(req
);
1931 if (messagePlist
!= NULL
) {
1932 pthread_cleanup_push(plist_cleanup
, (void *)messagePlist
);
1933 plist_t item
= plist_dict_get_item(messagePlist
, "networkTimeSecs");
1935 plist_t item_2
= plist_dict_get_item(messagePlist
, "networkTimeTimelineID");
1936 if (item_2
== NULL
) {
1937 debug(1, "Can't identify the Clock ID of the player.");
1940 plist_get_uint_val(item_2
, &nid
);
1941 debug(2, "networkTimeTimelineID \"%" PRIx64
"\".", nid
);
1942 conn
->networkTimeTimelineID
= nid
;
1944 uint64_t networkTimeSecs
;
1945 plist_get_uint_val(item
, &networkTimeSecs
);
1946 debug(2, "anchor networkTimeSecs is %" PRIu64
".", networkTimeSecs
);
1948 item
= plist_dict_get_item(messagePlist
, "networkTimeFrac");
1949 uint64_t networkTimeFrac
;
1950 plist_get_uint_val(item
, &networkTimeFrac
);
1951 debug(2, "anchor networkTimeFrac is 0%" PRIu64
".", networkTimeFrac
);
1952 // it looks like the networkTimeFrac is a fraction where the msb is work 1/2, the
1953 // next 1/4 and so on
1954 // now, convert the network time and fraction into nanoseconds
1955 networkTimeFrac
= networkTimeFrac
>> 32; // reduce precision to about 1/4 nanosecond
1956 networkTimeFrac
= networkTimeFrac
* 1000000000;
1957 networkTimeFrac
= networkTimeFrac
>> 32; // we should now be left with the ns
1959 networkTimeSecs
= networkTimeSecs
* 1000000000; // turn the whole seconds into ns
1960 uint64_t anchorTimeNanoseconds
= networkTimeSecs
+ networkTimeFrac
;
1962 debug(2, "anchorTimeNanoseconds looks like %" PRIu64
".", anchorTimeNanoseconds
);
1964 item
= plist_dict_get_item(messagePlist
, "rtpTime");
1967 plist_get_uint_val(item
, &rtpTime
);
1968 // debug(1, "anchor rtpTime is %" PRId64 ".", rtpTime);
1969 uint32_t anchorRTPTime
= rtpTime
;
1971 int32_t added_latency
= (int32_t)(config
.audio_backend_latency_offset
* conn
->input_rate
);
1972 // debug(1,"anchorRTPTime: %" PRIu32 ", added latency: %" PRId32 ".", anchorRTPTime,
1974 set_ptp_anchor_info(conn
, conn
->networkTimeTimelineID
, anchorRTPTime
- added_latency
,
1975 anchorTimeNanoseconds
);
1978 item
= plist_dict_get_item(messagePlist
, "rate");
1981 plist_get_uint_val(item
, &rate
);
1982 debug(3, "anchor rate 0x%016" PRIx64
".", rate
);
1983 debug_mutex_lock(&conn
->flush_mutex
, 1000, 1);
1984 pthread_cleanup_push(mutex_unlock
, &conn
->flush_mutex
);
1985 conn
->ap2_rate
= rate
;
1986 if ((rate
& 1) != 0) {
1987 ptp_send_control_message_string(
1988 "B"); // signify clock dependability period is "B"eginning (or resuming)
1989 debug(2, "Connection %d: Start playing, with anchor clock %" PRIx64
".",
1990 conn
->connection_number
, conn
->networkTimeTimelineID
);
1991 activity_monitor_signify_activity(1);
1993 #ifdef CONFIG_METADATA
1994 send_ssnc_metadata('pres', NULL
, 0, 1); // resume -- contains cancellation points
1996 conn
->ap2_play_enabled
= 1;
1998 ptp_send_control_message_string("P"); // signify play is "P"ausing
1999 debug(2, "Connection %d: Pause playing.", conn
->connection_number
);
2000 conn
->ap2_play_enabled
= 0;
2001 activity_monitor_signify_activity(0);
2002 reset_anchor_info(conn
);
2003 #ifdef CONFIG_METADATA
2004 send_ssnc_metadata('paus', NULL
, 0, 1); // pause -- contains cancellation points
2006 if (config
.output
->stop
) {
2007 debug(2, "Connection %d: Stop the output backend.", conn
->connection_number
);
2008 config
.output
->stop();
2011 pthread_cleanup_pop(1); // unlock the conn->flush_mutex
2013 pthread_cleanup_pop(1); // plist_free the messagePlist;
2015 debug(1, "missing plist!");
2017 resp
->respcode
= 200;
2020 void handle_get(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2021 debug(2, "Connection %d: GET %s :: Content-Length %d", conn
->connection_number
, req
->path
,
2022 req
->contentlength
);
2023 debug_log_rtsp_message(2, "GET request", req
);
2024 if (strcmp(req
->path
, "/info") == 0) {
2025 handle_get_info(conn
, req
, resp
);
2027 debug(1, "Unhandled GET, path \"%s\".", req
->path
);
2028 resp
->respcode
= 501; // Not Implemented
2033 void handle_get(__attribute((unused
)) rtsp_conn_info
*conn
, __attribute((unused
)) rtsp_message
*req
,
2034 __attribute((unused
)) rtsp_message
*resp
) {
2035 debug(1, "Connection %d: GET %s Content-Length %d", conn
->connection_number
, req
->path
,
2036 req
->contentlength
);
2037 resp
->respcode
= 500;
2040 void handle_post(rtsp_conn_info
*conn
, rtsp_message
*req
,
2041 __attribute((unused
)) rtsp_message
*resp
) {
2042 debug(1, "Connection %d: POST %s Content-Length %d", conn
->connection_number
, req
->path
,
2043 req
->contentlength
);
2044 resp
->respcode
= 500;
2048 #ifdef CONFIG_AIRPLAY_2
2050 char device_id
[PAIR_AP_DEVICE_ID_LEN_MAX
];
2051 uint8_t public_key
[32];
2053 struct pairings
*next
;
2056 static struct pairings
*pairing_find(const char *device_id
) {
2057 for (struct pairings
*pairing
= pairings
; pairing
; pairing
= pairing
->next
) {
2058 if (strcmp(device_id
, pairing
->device_id
) == 0)
2064 static void pairing_add(uint8_t public_key
[32], const char *device_id
) {
2065 struct pairings
*pairing
= calloc(1, sizeof(struct pairings
));
2066 snprintf(pairing
->device_id
, sizeof(pairing
->device_id
), "%s", device_id
);
2067 memcpy(pairing
->public_key
, public_key
, sizeof(pairing
->public_key
));
2069 pairing
->next
= pairings
;
2073 static void pairing_remove(struct pairings
*pairing
) {
2074 if (pairing
== pairings
) {
2075 pairings
= pairing
->next
;
2077 struct pairings
*iter
;
2078 for (iter
= pairings
; iter
&& (iter
->next
!= pairing
); iter
= iter
->next
)
2082 iter
->next
= pairing
->next
;
2088 static int pairing_add_cb(uint8_t public_key
[32], const char *device_id
,
2089 void *cb_arg
__attribute__((unused
))) {
2090 debug(1, "pair-add cb for %s", device_id
);
2092 struct pairings
*pairing
= pairing_find(device_id
);
2094 memcpy(pairing
->public_key
, public_key
, sizeof(pairing
->public_key
));
2098 pairing_add(public_key
, device_id
);
2102 static int pairing_remove_cb(uint8_t public_key
[32] __attribute__((unused
)), const char *device_id
,
2103 void *cb_arg
__attribute__((unused
))) {
2104 debug(1, "pair-remove cb for %s", device_id
);
2106 struct pairings
*pairing
= pairing_find(device_id
);
2108 debug(1, "pair-remove callback for unknown device");
2112 pairing_remove(pairing
);
2116 static void pairing_list_cb(pair_cb enum_cb
, void *enum_cb_arg
,
2117 void *cb_arg
__attribute__((unused
))) {
2118 debug(2, "pair-list cb");
2120 for (struct pairings
*pairing
= pairings
; pairing
; pairing
= pairing
->next
) {
2121 enum_cb(pairing
->public_key
, pairing
->device_id
, enum_cb_arg
);
2125 void handle_pair_add(rtsp_conn_info
*conn
__attribute__((unused
)), rtsp_message
*req
,
2126 rtsp_message
*resp
) {
2127 uint8_t *body
= NULL
;
2128 size_t body_len
= 0;
2129 int ret
= pair_add(PAIR_SERVER_HOMEKIT
, &body
, &body_len
, pairing_add_cb
, NULL
,
2130 (const uint8_t *)req
->content
, req
->contentlength
);
2132 debug(1, "pair-add returned an error");
2133 resp
->respcode
= 451;
2136 resp
->content
= (char *)body
; // these will be freed when the data is sent
2137 resp
->contentlength
= body_len
;
2138 msg_add_header(resp
, "Content-Type", "application/octet-stream");
2139 debug_log_rtsp_message(2, "pair-add response", resp
);
2142 void handle_pair_list(rtsp_conn_info
*conn
__attribute__((unused
)), rtsp_message
*req
,
2143 rtsp_message
*resp
) {
2144 uint8_t *body
= NULL
;
2145 size_t body_len
= 0;
2146 int ret
= pair_list(PAIR_SERVER_HOMEKIT
, &body
, &body_len
, pairing_list_cb
, NULL
,
2147 (const uint8_t *)req
->content
, req
->contentlength
);
2149 debug(1, "pair-list returned an error");
2150 resp
->respcode
= 451;
2153 resp
->content
= (char *)body
; // these will be freed when the data is sent
2154 resp
->contentlength
= body_len
;
2155 msg_add_header(resp
, "Content-Type", "application/octet-stream");
2156 debug_log_rtsp_message(2, "pair-list response", resp
);
2159 void handle_pair_remove(rtsp_conn_info
*conn
__attribute__((unused
)), rtsp_message
*req
,
2160 rtsp_message
*resp
) {
2161 uint8_t *body
= NULL
;
2162 size_t body_len
= 0;
2163 int ret
= pair_remove(PAIR_SERVER_HOMEKIT
, &body
, &body_len
, pairing_remove_cb
, NULL
,
2164 (const uint8_t *)req
->content
, req
->contentlength
);
2166 debug(1, "pair-remove returned an error");
2167 resp
->respcode
= 451;
2170 resp
->content
= (char *)body
; // these will be freed when the data is sent
2171 resp
->contentlength
= body_len
;
2172 msg_add_header(resp
, "Content-Type", "application/octet-stream");
2173 debug_log_rtsp_message(2, "pair-remove response", resp
);
2176 void handle_pair_verify(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2178 uint8_t *body
= NULL
;
2179 size_t body_len
= 0;
2180 struct pair_result
*result
;
2181 debug(2, "Connection %d: pair-verify Content-Length %d", conn
->connection_number
,
2182 req
->contentlength
);
2184 if (!conn
->ap2_pairing_context
.verify_ctx
) {
2185 conn
->ap2_pairing_context
.verify_ctx
=
2186 pair_verify_new(PAIR_SERVER_HOMEKIT
, NULL
, NULL
, NULL
, config
.airplay_device_id
);
2187 if (!conn
->ap2_pairing_context
.verify_ctx
) {
2188 debug(1, "Error creating verify context");
2189 resp
->respcode
= 500; // Internal Server Error
2194 ret
= pair_verify(&body
, &body_len
, conn
->ap2_pairing_context
.verify_ctx
,
2195 (const uint8_t *)req
->content
, req
->contentlength
);
2197 debug(1, pair_verify_errmsg(conn
->ap2_pairing_context
.verify_ctx
));
2198 resp
->respcode
= 470; // Connection Authorization Required
2202 ret
= pair_verify_result(&result
, conn
->ap2_pairing_context
.verify_ctx
);
2203 if (ret
== 0 && result
->shared_secret_len
> 0) {
2204 conn
->ap2_pairing_context
.control_cipher_bundle
.cipher_ctx
=
2205 pair_cipher_new(PAIR_SERVER_HOMEKIT
, 2, result
->shared_secret
, result
->shared_secret_len
);
2206 if (!conn
->ap2_pairing_context
.control_cipher_bundle
.cipher_ctx
) {
2207 debug(1, "Error setting up rtsp control channel ciphering\n");
2213 resp
->content
= (char *)body
; // these will be freed when the data is sent
2214 resp
->contentlength
= body_len
;
2216 msg_add_header(resp
, "Content-Type", "application/octet-stream");
2217 debug_log_rtsp_message(2, "pair-verify response", resp
);
2220 void handle_pair_setup(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2222 uint8_t *body
= NULL
;
2223 size_t body_len
= 0;
2224 struct pair_result
*result
;
2225 debug(2, "Connection %d: handle_pair-setup Content-Length %d", conn
->connection_number
,
2226 req
->contentlength
);
2228 if (!conn
->ap2_pairing_context
.setup_ctx
) {
2229 conn
->ap2_pairing_context
.setup_ctx
= pair_setup_new(PAIR_SERVER_HOMEKIT
, config
.airplay_pin
,
2230 NULL
, NULL
, config
.airplay_device_id
);
2231 if (!conn
->ap2_pairing_context
.setup_ctx
) {
2232 debug(1, "Error creating setup context");
2233 resp
->respcode
= 500; // Internal Server Error
2238 ret
= pair_setup(&body
, &body_len
, conn
->ap2_pairing_context
.setup_ctx
,
2239 (const uint8_t *)req
->content
, req
->contentlength
);
2241 debug(1, pair_setup_errmsg(conn
->ap2_pairing_context
.setup_ctx
));
2242 resp
->respcode
= 470; // Connection Authorization Required
2246 ret
= pair_setup_result(NULL
, &result
, conn
->ap2_pairing_context
.setup_ctx
);
2247 if (ret
== 0 && result
->shared_secret_len
> 0) {
2248 // Transient pairing completed (pair-setup step 2), prepare encryption, but
2249 // don't activate yet, the response to this request is still plaintext
2250 conn
->ap2_pairing_context
.control_cipher_bundle
.cipher_ctx
=
2251 pair_cipher_new(PAIR_SERVER_HOMEKIT
, 2, result
->shared_secret
, result
->shared_secret_len
);
2252 if (!conn
->ap2_pairing_context
.control_cipher_bundle
.cipher_ctx
) {
2253 debug(1, "Error setting up rtsp control channel ciphering\n");
2259 resp
->content
= (char *)body
; // these will be freed when the data is sent
2260 resp
->contentlength
= body_len
;
2262 msg_add_header(resp
, "Content-Type", "application/octet-stream");
2263 debug_log_rtsp_message(2, "pair-setup response", resp
);
2266 void handle_fp_setup(__attribute__((unused
)) rtsp_conn_info
*conn
, rtsp_message
*req
,
2267 rtsp_message
*resp
) {
2269 /* Fairplay magic */
2270 static uint8_t server_fp_reply1
[] =
2271 "\x46\x50\x4c\x59\x03\x01\x02\x00\x00\x00\x00\x82\x02\x00\x0f\x9f\x3f\x9e\x0a"
2272 "\x25\x21\xdb\xdf\x31\x2a\xb2\xbf\xb2\x9e\x8d\x23\x2b\x63\x76\xa8\xc8\x18\x70"
2273 "\x1d\x22\xae\x93\xd8\x27\x37\xfe\xaf\x9d\xb4\xfd\xf4\x1c\x2d\xba\x9d\x1f\x49"
2274 "\xca\xaa\xbf\x65\x91\xac\x1f\x7b\xc6\xf7\xe0\x66\x3d\x21\xaf\xe0\x15\x65\x95"
2275 "\x3e\xab\x81\xf4\x18\xce\xed\x09\x5a\xdb\x7c\x3d\x0e\x25\x49\x09\xa7\x98\x31"
2276 "\xd4\x9c\x39\x82\x97\x34\x34\xfa\xcb\x42\xc6\x3a\x1c\xd9\x11\xa6\xfe\x94\x1a"
2277 "\x8a\x6d\x4a\x74\x3b\x46\xc3\xa7\x64\x9e\x44\xc7\x89\x55\xe4\x9d\x81\x55\x00"
2278 "\x95\x49\xc4\xe2\xf7\xa3\xf6\xd5\xba";
2279 static uint8_t server_fp_reply2
[] =
2280 "\x46\x50\x4c\x59\x03\x01\x02\x00\x00\x00\x00\x82\x02\x01\xcf\x32\xa2\x57\x14"
2281 "\xb2\x52\x4f\x8a\xa0\xad\x7a\xf1\x64\xe3\x7b\xcf\x44\x24\xe2\x00\x04\x7e\xfc"
2282 "\x0a\xd6\x7a\xfc\xd9\x5d\xed\x1c\x27\x30\xbb\x59\x1b\x96\x2e\xd6\x3a\x9c\x4d"
2283 "\xed\x88\xba\x8f\xc7\x8d\xe6\x4d\x91\xcc\xfd\x5c\x7b\x56\xda\x88\xe3\x1f\x5c"
2284 "\xce\xaf\xc7\x43\x19\x95\xa0\x16\x65\xa5\x4e\x19\x39\xd2\x5b\x94\xdb\x64\xb9"
2285 "\xe4\x5d\x8d\x06\x3e\x1e\x6a\xf0\x7e\x96\x56\x16\x2b\x0e\xfa\x40\x42\x75\xea"
2286 "\x5a\x44\xd9\x59\x1c\x72\x56\xb9\xfb\xe6\x51\x38\x98\xb8\x02\x27\x72\x19\x88"
2287 "\x57\x16\x50\x94\x2a\xd9\x46\x68\x8a";
2288 static uint8_t server_fp_reply3
[] =
2289 "\x46\x50\x4c\x59\x03\x01\x02\x00\x00\x00\x00\x82\x02\x02\xc1\x69\xa3\x52\xee"
2290 "\xed\x35\xb1\x8c\xdd\x9c\x58\xd6\x4f\x16\xc1\x51\x9a\x89\xeb\x53\x17\xbd\x0d"
2291 "\x43\x36\xcd\x68\xf6\x38\xff\x9d\x01\x6a\x5b\x52\xb7\xfa\x92\x16\xb2\xb6\x54"
2292 "\x82\xc7\x84\x44\x11\x81\x21\xa2\xc7\xfe\xd8\x3d\xb7\x11\x9e\x91\x82\xaa\xd7"
2293 "\xd1\x8c\x70\x63\xe2\xa4\x57\x55\x59\x10\xaf\x9e\x0e\xfc\x76\x34\x7d\x16\x40"
2294 "\x43\x80\x7f\x58\x1e\xe4\xfb\xe4\x2c\xa9\xde\xdc\x1b\x5e\xb2\xa3\xaa\x3d\x2e"
2295 "\xcd\x59\xe7\xee\xe7\x0b\x36\x29\xf2\x2a\xfd\x16\x1d\x87\x73\x53\xdd\xb9\x9a"
2296 "\xdc\x8e\x07\x00\x6e\x56\xf8\x50\xce";
2297 static uint8_t server_fp_reply4
[] =
2298 "\x46\x50\x4c\x59\x03\x01\x02\x00\x00\x00\x00\x82\x02\x03\x90\x01\xe1\x72\x7e"
2299 "\x0f\x57\xf9\xf5\x88\x0d\xb1\x04\xa6\x25\x7a\x23\xf5\xcf\xff\x1a\xbb\xe1\xe9"
2300 "\x30\x45\x25\x1a\xfb\x97\xeb\x9f\xc0\x01\x1e\xbe\x0f\x3a\x81\xdf\x5b\x69\x1d"
2301 "\x76\xac\xb2\xf7\xa5\xc7\x08\xe3\xd3\x28\xf5\x6b\xb3\x9d\xbd\xe5\xf2\x9c\x8a"
2302 "\x17\xf4\x81\x48\x7e\x3a\xe8\x63\xc6\x78\x32\x54\x22\xe6\xf7\x8e\x16\x6d\x18"
2303 "\xaa\x7f\xd6\x36\x25\x8b\xce\x28\x72\x6f\x66\x1f\x73\x88\x93\xce\x44\x31\x1e"
2304 "\x4b\xe6\xc0\x53\x51\x93\xe5\xef\x72\xe8\x68\x62\x33\x72\x9c\x22\x7d\x82\x0c"
2305 "\x99\x94\x45\xd8\x92\x46\xc8\xc3\x59";
2307 static uint8_t server_fp_header
[] = "\x46\x50\x4c\x59\x03\x01\x04\x00\x00\x00\x00\x14";
2309 resp
->respcode
= 200; // assume it's handled
2313 int version_pos
= 4;
2317 int setup_message_type
= 1;
2318 int setup1_message_seq
= 1;
2319 int setup2_message_seq
= 3;
2320 int setup2_suffix_len
= 20;
2323 // response and len are dummy values and can be ignored
2325 // debug(1, "Version: %02x, mode: %02x, type: %02x, seq: %02x", req->content[version_pos],
2326 // req->content[mode_pos], req->content[type_pos], req->content[seq_pos]);
2328 if (req
->content
[version_pos
] != 3 || req
->content
[type_pos
] != setup_message_type
) {
2329 debug(1, "Unsupported FP version.");
2332 char *response
= NULL
;
2335 if (req
->content
[seq_pos
] == setup1_message_seq
) {
2336 // All replies are the same length. -1 to account for the NUL byte at the end.
2337 len
= sizeof(server_fp_reply1
) - 1;
2339 if (req
->content
[mode_pos
] == 0)
2340 response
= memdup(server_fp_reply1
, len
);
2341 if (req
->content
[mode_pos
] == 1)
2342 response
= memdup(server_fp_reply2
, len
);
2343 if (req
->content
[mode_pos
] == 2)
2344 response
= memdup(server_fp_reply3
, len
);
2345 if (req
->content
[mode_pos
] == 3)
2346 response
= memdup(server_fp_reply4
, len
);
2348 } else if (req
->content
[seq_pos
] == setup2_message_seq
) {
2349 // -1 to account for the NUL byte at the end.
2350 len
= sizeof(server_fp_header
) - 1 + setup2_suffix_len
;
2351 response
= malloc(len
);
2353 memcpy(response
, server_fp_header
, sizeof(server_fp_header
) - 1);
2354 memcpy(response
+ sizeof(server_fp_header
) - 1,
2355 req
->content
+ req
->contentlength
- setup2_suffix_len
, setup2_suffix_len
);
2359 if (response
== NULL
) {
2360 debug(1, "Cannot create a response.");
2363 resp
->content
= response
; // these will be freed when the data is sent
2364 resp
->contentlength
= len
;
2365 msg_add_header(resp
, "Content-Type", "application/octet-stream");
2369 <key>Identifier</key>
2370 <string>21cc689d-d5de-4814-872c-71d1426b57e0</string>
2371 <key>Enable_HK_Access_Control</key>
2373 <key>PublicKey</key>
2375 qXJDhhL5F3OACL+HO7LVLQVdy0OJtavepjpF720PaOQ=
2377 <key>Device_Name</key>
2378 <string>MyDevice</string>
2379 <key>Access_Control_Level</key>
2380 <integer>0</integer>
2382 void handle_configure(rtsp_conn_info
*conn
__attribute__((unused
)),
2383 rtsp_message
*req
__attribute__((unused
)), rtsp_message
*resp
) {
2384 uint8_t public_key
[32];
2386 pair_public_key_get(PAIR_SERVER_HOMEKIT
, public_key
, config
.airplay_device_id
);
2388 plist_t response_plist
= plist_new_dict();
2390 plist_dict_set_item(response_plist
, "Identifier", plist_new_string(config
.airplay_pi
));
2391 plist_dict_set_item(response_plist
, "Enable_HK_Access_Control", plist_new_bool(1));
2392 plist_dict_set_item(response_plist
, "PublicKey",
2393 plist_new_data((const char *)public_key
, sizeof(public_key
)));
2394 plist_dict_set_item(response_plist
, "Device_Name", plist_new_string(config
.service_name
));
2395 plist_dict_set_item(response_plist
, "Access_Control_Level", plist_new_uint(0));
2397 plist_to_bin(response_plist
, &resp
->content
, &resp
->contentlength
);
2398 plist_free(response_plist
);
2400 msg_add_header(resp
, "Content-Type", "application/x-apple-binary-plist");
2401 debug_log_rtsp_message(2, "POST /configure response:", resp
);
2404 void handle_feedback(rtsp_conn_info
*conn
, __attribute__((unused
)) rtsp_message
*req
,
2405 __attribute__((unused
)) rtsp_message
*resp
) {
2406 debug(2, "Connection %d: POST %s Content-Length %d", conn
->connection_number
, req
->path
,
2407 req
->contentlength
);
2408 debug_log_rtsp_message(2, NULL
, req
);
2409 if (conn
->airplay_stream_category
== remote_control_stream
) {
2410 plist_t array_plist
= plist_new_array();
2412 plist_t response_plist
= plist_new_dict();
2413 plist_dict_set_item(response_plist
, "streams", array_plist
);
2415 plist_to_bin(response_plist
, &resp
->content
, &resp
->contentlength
);
2416 plist_free(response_plist
);
2418 msg_add_header(resp
, "Content-Type", "application/x-apple-binary-plist");
2419 debug_log_rtsp_message(2, "FEEDBACK response (remote_control_stream):", resp
);
2423 plist_t payload_plist = plist_new_dict();
2424 plist_dict_set_item(payload_plist, "type", plist_new_uint(103));
2425 plist_dict_set_item(payload_plist, "sr", plist_new_real(44100.0));
2427 plist_t array_plist = plist_new_array();
2428 plist_array_append_item(array_plist, payload_plist);
2430 plist_t response_plist = plist_new_dict();
2431 plist_dict_set_item(response_plist, "streams",array_plist);
2433 plist_to_bin(response_plist, &resp->content, &resp->contentlength);
2434 plist_free(response_plist);
2435 // plist_free(array_plist);
2436 // plist_free(payload_plist);
2438 msg_add_header(resp, "Content-Type", "application/x-apple-binary-plist");
2439 debug_log_rtsp_message(2, "FEEDBACK response:", resp);
2443 void handle_command(__attribute__((unused
)) rtsp_conn_info
*conn
, rtsp_message
*req
,
2444 __attribute__((unused
)) rtsp_message
*resp
) {
2445 debug(2, "Connection %d: POST %s Content-Length %d", conn
->connection_number
, req
->path
,
2446 req
->contentlength
);
2447 debug_log_rtsp_message(2, NULL
, req
);
2448 if (rtsp_message_contains_plist(req
)) {
2449 plist_t command_dict
= NULL
;
2450 plist_from_memory(req
->content
, req
->contentlength
, &command_dict
);
2451 if (command_dict
!= NULL
) {
2452 // we have a plist -- try to get the dict item keyed to "updateMRSupportedCommands"
2453 plist_t item
= plist_dict_get_item(command_dict
, "type");
2455 char *typeValue
= NULL
;
2456 plist_get_string_val(item
, &typeValue
);
2457 if ((typeValue
!= NULL
) && (strcmp(typeValue
, "updateMRSupportedCommands") == 0)) {
2458 item
= plist_dict_get_item(command_dict
, "params");
2460 // the item should be a dict
2461 plist_t item_array
= plist_dict_get_item(item
, "mrSupportedCommandsFromSender");
2462 if (item_array
!= NULL
) {
2463 // here we have an array of data items
2464 uint32_t items
= plist_array_get_size(item_array
);
2466 uint32_t item_number
;
2467 for (item_number
= 0; item_number
< items
; item_number
++) {
2468 plist_t the_item
= plist_array_get_item(item_array
, item_number
);
2470 uint64_t length
= 0;
2471 plist_get_data_val(the_item
, &buff
, &length
);
2472 // debug(1,"Item %d, length: %" PRId64 " bytes", item_number, length);
2473 if ((buff
!= NULL
) && (length
>= strlen("bplist00")) &&
2474 (strstr(buff
, "bplist00") == buff
)) {
2475 // debug(1,"Contains a plist.");
2476 plist_t subsidiary_plist
= NULL
;
2477 plist_from_memory(buff
, length
, &subsidiary_plist
);
2478 if (subsidiary_plist
) {
2479 char *printable_plist
= plist_content(subsidiary_plist
);
2480 if (printable_plist
) {
2481 debug(3, "\n%s", printable_plist
);
2482 free(printable_plist
);
2484 debug(1, "Can't print the plist!");
2486 // plist_free(subsidiary_plist);
2488 debug(1, "Can't access the plist!");
2496 debug(1, "POST /command no mrSupportedCommandsFromSender item.");
2499 debug(1, "POST /command no params dict.");
2501 resp
->respcode
= 400; // say it's a bad request
2504 "POST /command plist type is \"%s\", but \"updateMRSupportedCommands\" expected.",
2507 if (typeValue
!= NULL
)
2510 debug(2, "Could not find a \"type\" item.");
2513 plist_free(command_dict
);
2515 debug(1, "POST /command plist cannot be inputted.");
2518 debug(1, "POST /command contains no plist");
2522 void handle_audio_mode(rtsp_conn_info
*conn
, rtsp_message
*req
,
2523 __attribute__((unused
)) rtsp_message
*resp
) {
2524 debug(2, "Connection %d: POST %s Content-Length %d", conn
->connection_number
, req
->path
,
2525 req
->contentlength
);
2526 debug_log_rtsp_message(2, NULL
, req
);
2529 void handle_post(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2530 resp
->respcode
= 200;
2531 if (strcmp(req
->path
, "/pair-setup") == 0) {
2532 handle_pair_setup(conn
, req
, resp
);
2533 } else if (strcmp(req
->path
, "/pair-verify") == 0) {
2534 handle_pair_verify(conn
, req
, resp
);
2535 } else if (strcmp(req
->path
, "/pair-add") == 0) {
2536 handle_pair_add(conn
, req
, resp
);
2537 } else if (strcmp(req
->path
, "/pair-remove") == 0) {
2538 handle_pair_remove(conn
, req
, resp
);
2539 } else if (strcmp(req
->path
, "/pair-list") == 0) {
2540 handle_pair_list(conn
, req
, resp
);
2541 } else if (strcmp(req
->path
, "/fp-setup") == 0) {
2542 handle_fp_setup(conn
, req
, resp
);
2543 } else if (strcmp(req
->path
, "/configure") == 0) {
2544 handle_configure(conn
, req
, resp
);
2545 } else if (strcmp(req
->path
, "/feedback") == 0) {
2546 handle_feedback(conn
, req
, resp
);
2547 } else if (strcmp(req
->path
, "/command") == 0) {
2548 handle_command(conn
, req
, resp
);
2549 } else if (strcmp(req
->path
, "/audioMode") == 0) {
2550 handle_audio_mode(conn
, req
, resp
);
2552 debug(1, "Connection %d: Unhandled POST %s Content-Length %d", conn
->connection_number
,
2553 req
->path
, req
->contentlength
);
2554 debug_log_rtsp_message(2, "POST request", req
);
2558 void handle_setpeers(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2559 debug(2, "Connection %d: SETPEERS %s Content-Length %d", conn
->connection_number
, req
->path
,
2560 req
->contentlength
);
2561 debug_log_rtsp_message(2, "SETPEERS request", req
);
2563 char timing_list_message[4096];
2564 timing_list_message[0] = 'T';
2565 timing_list_message[1] = 0;
2567 // ensure the client itself is first -- it's okay if it's duplicated later
2568 strncat(timing_list_message, " ", sizeof(timing_list_message) - 1 -
2569 strlen(timing_list_message)); strncat(timing_list_message, (const char
2570 *)&conn->client_ip_string, sizeof(timing_list_message) - 1 - strlen(timing_list_message));
2572 plist_t addresses_array = NULL;
2573 plist_from_memory(req->content, req->contentlength, &addresses_array);
2574 uint32_t items = plist_array_get_size(addresses_array);
2577 for (item = 0; item < items; item++) {
2578 plist_t n = plist_array_get_item(addresses_array, item);
2579 char *ip_address = NULL;
2580 plist_get_string_val(n, &ip_address);
2581 // debug(1,ip_address);
2582 strncat(timing_list_message, " ",
2583 sizeof(timing_list_message) - 1 - strlen(timing_list_message));
2584 strncat(timing_list_message, ip_address,
2585 sizeof(timing_list_message) - 1 - strlen(timing_list_message));
2586 if (ip_address != NULL)
2589 ptp_send_control_message_string(timing_list_message);
2591 plist_free(addresses_array);
2593 // set_client_as_ptp_clock(conn);
2594 resp
->respcode
= 200;
2598 #ifndef CONFIG_AIRPLAY_2
2599 void handle_options(rtsp_conn_info
*conn
, __attribute__((unused
)) rtsp_message
*req
,
2600 rtsp_message
*resp
) {
2601 debug_log_rtsp_message(2, "OPTIONS request", req
);
2602 debug(3, "Connection %d: OPTIONS", conn
->connection_number
);
2603 resp
->respcode
= 200;
2604 msg_add_header(resp
, "Public",
2605 "ANNOUNCE, SETUP, RECORD, "
2606 "PAUSE, FLUSH, TEARDOWN, "
2607 "OPTIONS, GET_PARAMETER, SET_PARAMETER");
2611 #ifdef CONFIG_AIRPLAY_2
2613 void handle_options(rtsp_conn_info
*conn
, __attribute__((unused
)) rtsp_message
*req
,
2614 rtsp_message
*resp
) {
2615 debug_log_rtsp_message(2, "OPTIONS request", req
);
2616 debug(3, "Connection %d: OPTIONS", conn
->connection_number
);
2617 resp
->respcode
= 200;
2618 msg_add_header(resp
, "Public",
2619 "ANNOUNCE, SETUP, RECORD, "
2620 "PAUSE, FLUSH, FLUSHBUFFERED, TEARDOWN, "
2621 "OPTIONS, POST, GET, PUT");
2624 void teardown_phase_one(rtsp_conn_info
*conn
) {
2625 // this can be called more than once on the same connection --
2626 // by the player itself but also by the play session being killed
2627 if (conn
->player_thread
) {
2628 player_stop(conn
); // this nulls the player_thread
2629 activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
2631 if (conn
->session_key
) {
2632 free(conn
->session_key
);
2633 conn
->session_key
= NULL
;
2637 void teardown_phase_two(rtsp_conn_info
*conn
) {
2638 // we are being asked to disconnect
2639 // this can be called more than once on the same connection --
2640 // by the player itself but also by the play seesion being killed
2641 debug(2, "Connection %d: TEARDOWN %s connection.", conn
->connection_number
,
2642 get_category_string(conn
->airplay_stream_category
));
2643 if (conn
->airplay_stream_category
== remote_control_stream
) {
2644 if (conn
->rtp_data_thread
) {
2645 debug(2, "Connection %d: TEARDOWN %s Delete Data Thread.", conn
->connection_number
,
2646 get_category_string(conn
->airplay_stream_category
));
2647 pthread_cancel(*conn
->rtp_data_thread
);
2648 pthread_join(*conn
->rtp_data_thread
, NULL
);
2649 free(conn
->rtp_data_thread
);
2650 conn
->rtp_data_thread
= NULL
;
2652 if (conn
->data_socket
) {
2653 debug(2, "Connection %d: TEARDOWN %s Close Data Socket.", conn
->connection_number
,
2654 get_category_string(conn
->airplay_stream_category
));
2655 close(conn
->data_socket
);
2656 conn
->data_socket
= 0;
2660 if (conn
->rtp_event_thread
) {
2661 debug(2, "Connection %d: TEARDOWN %s Delete Event Thread.", conn
->connection_number
,
2662 get_category_string(conn
->airplay_stream_category
));
2663 pthread_cancel(*conn
->rtp_event_thread
);
2664 pthread_join(*conn
->rtp_event_thread
, NULL
);
2665 free(conn
->rtp_event_thread
);
2666 conn
->rtp_event_thread
= NULL
;
2668 if (conn
->event_socket
) {
2669 debug(2, "Connection %d: TEARDOWN %s Close Event Socket.", conn
->connection_number
,
2670 get_category_string(conn
->airplay_stream_category
));
2671 close(conn
->event_socket
);
2672 conn
->event_socket
= 0;
2675 // if we are closing a PTP stream only, do this
2676 if (conn
->airplay_stream_category
== ptp_stream
) {
2677 if (conn
->airplay_gid
!= NULL
) {
2678 free(conn
->airplay_gid
);
2679 conn
->airplay_gid
= NULL
;
2681 #ifdef CONFIG_METADATA
2682 // this is here to ensure it's only performed once during a teardown of a ptp stream
2683 send_ssnc_metadata('disc', conn
->client_ip_string
, strlen(conn
->client_ip_string
), 1);
2686 conn
->groupContainsGroupLeader
= 0;
2687 config
.airplay_statusflags
&= (0xffffffff - (1 << 11)); // DeviceSupportsRelay
2688 build_bonjour_strings(NULL
);
2689 debug(2, "Connection %d: TEARDOWN mdns_update on %s.", conn
->connection_number
,
2690 get_category_string(conn
->airplay_stream_category
));
2691 mdns_update(NULL
, secondary_txt_records
);
2692 if (conn
->dacp_active_remote
!= NULL
) {
2693 free(conn
->dacp_active_remote
);
2694 conn
->dacp_active_remote
= NULL
;
2700 void handle_teardown_2(rtsp_conn_info
*conn
, __attribute__((unused
)) rtsp_message
*req
,
2701 rtsp_message
*resp
) {
2703 debug(2, "Connection %d: TEARDOWN %s.", conn
->connection_number
,
2704 get_category_string(conn
->airplay_stream_category
));
2705 debug_log_rtsp_message(2, "TEARDOWN: ", req
);
2706 // if (have_player(conn)) {
2707 resp
->respcode
= 200;
2708 msg_add_header(resp
, "Connection", "close");
2710 plist_t messagePlist
= plist_from_rtsp_content(req
);
2711 if (messagePlist
!= NULL
) {
2712 // now see if the incoming plist contains a "streams" array
2713 plist_t streams
= plist_dict_get_item(messagePlist
, "streams");
2716 debug(2, "Connection %d: TEARDOWN %s -- close the stream.", conn
->connection_number
,
2717 get_category_string(conn
->airplay_stream_category
));
2718 // we are being asked to close a stream
2719 teardown_phase_one(conn
);
2720 plist_free(streams
);
2721 debug(2, "Connection %d: TEARDOWN %s -- close the stream complete", conn
->connection_number
,
2722 get_category_string(conn
->airplay_stream_category
));
2724 debug(2, "Connection %d: TEARDOWN %s -- close the connection.", conn
->connection_number
,
2725 get_category_string(conn
->airplay_stream_category
));
2726 teardown_phase_one(conn
); // try to do phase one anyway
2727 teardown_phase_two(conn
);
2728 debug(2, "Connection %d: TEARDOWN %s -- close the connection complete",
2729 conn
->connection_number
, get_category_string(conn
->airplay_stream_category
));
2730 release_play_lock(conn
);
2733 plist_free(messagePlist
);
2734 resp
->respcode
= 200;
2736 debug(1, "Connection %d: missing plist!", conn
->connection_number
);
2737 resp
->respcode
= 451; // don't know what to do here
2739 // debug(1,"Bogus exit for valgrind -- remember to comment it out!.");
2740 // exit(EXIT_SUCCESS); //
2744 void teardown(rtsp_conn_info
*conn
) {
2746 activity_monitor_signify_activity(0); // inactive, and should be after command_stop()
2747 if (conn
->dacp_active_remote
!= NULL
) {
2748 free(conn
->dacp_active_remote
);
2749 conn
->dacp_active_remote
= NULL
;
2753 void handle_teardown(rtsp_conn_info
*conn
, __attribute__((unused
)) rtsp_message
*req
,
2754 rtsp_message
*resp
) {
2755 debug_log_rtsp_message(2, "TEARDOWN request", req
);
2756 debug(2, "Connection %d: TEARDOWN", conn
->connection_number
);
2757 // if (have_play_lock(conn)) {
2759 "TEARDOWN: synchronously terminating the player thread of RTSP conversation thread %d (2).",
2760 conn
->connection_number
);
2762 release_play_lock(conn
);
2764 resp
->respcode
= 200;
2765 msg_add_header(resp
, "Connection", "close");
2766 debug(3, "TEARDOWN: successful termination of playing thread of RTSP conversation thread %d.",
2767 conn
->connection_number
);
2769 // warn("Connection %d TEARDOWN received without having the player (no ANNOUNCE?)",
2770 // conn->connection_number);
2771 // resp->respcode = 451;
2773 // debug(1,"Bogus exit for valgrind -- remember to comment it out!.");
2774 // exit(EXIT_SUCCESS);
2777 void handle_flush(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2778 debug_log_rtsp_message(2, "FLUSH request", req
);
2779 debug(3, "Connection %d: FLUSH", conn
->connection_number
);
2781 uint32_t rtptime
= 0;
2782 char *hdr
= msg_get_header(req
, "RTP-Info");
2785 // debug(1,"FLUSH message received: \"%s\".",hdr);
2786 // get the rtp timestamp
2787 p
= strstr(hdr
, "rtptime=");
2791 rtptime
= uatoi(p
+ 1); // unsigned integer -- up to 2^32-1
2794 debug(2, "RTSP Flush Requested: %u.", rtptime
);
2796 if ((conn
!= NULL
) && (conn
== principal_conn
)) {
2797 #ifdef CONFIG_METADATA
2799 send_metadata('ssnc', 'flsr', p
+ 1, strlen(p
+ 1), req
, 1);
2801 send_metadata('ssnc', 'flsr', NULL
, 0, NULL
, 0);
2804 player_flush(rtptime
, conn
); // will not crash even it there is no player thread.
2805 resp
->respcode
= 200;
2808 warn("Connection %d FLUSH %u received without having the player", conn
->connection_number
,
2810 resp
->respcode
= 451;
2814 #ifdef CONFIG_AIRPLAY_2
2816 #ifdef CONFIG_METADATA
2817 static void check_and_send_plist_metadata(plist_t messagePlist
, const char *plist_key
,
2818 uint32_t metadata_code
) {
2819 plist_t item
= plist_dict_get_item(messagePlist
, plist_key
);
2822 plist_get_string_val(item
, &value
);
2823 if (value
!= NULL
) {
2824 send_metadata('ssnc', metadata_code
, value
, strlen(value
), NULL
, 0);
2831 void handle_setup_2(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
2833 debug(2, "Connection %d: SETUP (AirPlay 2)", conn
->connection_number
);
2834 debug_log_rtsp_message(2, "SETUP (AirPlay 2) SETUP incoming message", req
);
2836 plist_t messagePlist
= plist_from_rtsp_content(req
);
2837 plist_t setupResponsePlist
= plist_new_dict();
2838 resp
->respcode
= 400;
2840 // see if we can get a name for the client
2841 char *clientNameString
= NULL
;
2842 plist_t nameItem
= plist_dict_get_item(messagePlist
, "name");
2843 if (nameItem
!= NULL
) {
2844 plist_get_string_val(nameItem
, &clientNameString
);
2846 clientNameString
= strdup("<unknown>");
2849 // see if the incoming plist contains a "streams" array
2850 plist_t streams
= plist_dict_get_item(messagePlist
, "streams");
2851 if (streams
== NULL
) {
2852 // no "streams" plist, so it must (?) be an initial setup
2854 "Connection %d SETUP: No \"streams\" array has been found -- create an event thread "
2855 "and open a TCP port.",
2856 conn
->connection_number
);
2857 conn
->airplay_stream_category
= unspecified_stream_category
;
2859 // figure out what category of stream it is, by looking at the plist
2860 plist_t timingProtocol
= plist_dict_get_item(messagePlist
, "timingProtocol");
2861 if (timingProtocol
!= NULL
) {
2862 char *timingProtocolString
= NULL
;
2863 plist_get_string_val(timingProtocol
, &timingProtocolString
);
2864 if (timingProtocolString
) {
2865 if (strcmp(timingProtocolString
, "PTP") == 0) {
2866 debug(1, "Connection %d: AP2 PTP connection from %s:%u (\"%s\") to self at %s:%u.",
2867 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
2868 clientNameString
, conn
->self_ip_string
, conn
->self_rtsp_port
);
2869 conn
->airplay_stream_category
= ptp_stream
;
2870 conn
->timing_type
= ts_ptp
;
2871 } else if (strcmp(timingProtocolString
, "NTP") == 0) {
2872 debug(1, "Connection %d: SETUP: NTP setup from %s:%u (\"%s\") to self at %s:%u.",
2873 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
2874 clientNameString
, conn
->self_ip_string
, conn
->self_rtsp_port
);
2875 conn
->airplay_stream_category
= ntp_stream
;
2876 conn
->timing_type
= ts_ntp
;
2877 } else if (strcmp(timingProtocolString
, "None") == 0) {
2879 "Connection %d: SETUP: a \"None\" setup detected from %s:%u (\"%s\") to self at "
2881 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
2882 clientNameString
, conn
->self_ip_string
, conn
->self_rtsp_port
);
2883 // now check to see if it's got the "isRemoteControlOnly" item and check it's true
2884 plist_t isRemoteControlOnly
= plist_dict_get_item(messagePlist
, "isRemoteControlOnly");
2885 if (isRemoteControlOnly
!= NULL
) {
2886 uint8_t isRemoteControlOnlyBoolean
= 0;
2887 plist_get_bool_val(isRemoteControlOnly
, &isRemoteControlOnlyBoolean
);
2888 if (isRemoteControlOnlyBoolean
!= 0) {
2891 "Connection %d: Remote Control connection from %s:%u (\"%s\") to self at %s:%u.",
2892 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
2893 clientNameString
, conn
->self_ip_string
, conn
->self_rtsp_port
);
2894 conn
->airplay_stream_category
= remote_control_stream
;
2897 "Connection %d: SETUP: a \"None\" setup detected, with "
2898 "\"isRemoteControlOnly\" item set to \"false\".",
2899 conn
->connection_number
);
2903 "Connection %d: SETUP: a \"None\" setup detected, but no "
2904 "\"isRemoteControlOnly\" item detected.",
2905 conn
->connection_number
);
2909 // here, we know it's an initial setup and we know the kind of setup being requested
2910 // if it's a full service PTP stream, we get groupUUID, groupContainsGroupLeader and
2912 if (conn
->airplay_stream_category
== ptp_stream
) {
2914 // airplay 2 always allows interruption, so should never return -1
2915 if (get_play_lock(conn
, 1) != -1) {
2917 #ifdef CONFIG_METADATA
2918 send_ssnc_metadata('conn', conn
->client_ip_string
, strlen(conn
->client_ip_string
),
2919 1); // before disconnecting an existing play
2922 #ifdef CONFIG_METADATA
2923 send_ssnc_metadata('clip', conn
->client_ip_string
, strlen(conn
->client_ip_string
), 1);
2924 send_ssnc_metadata('svip', conn
->self_ip_string
, strlen(conn
->self_ip_string
), 1);
2927 if (ptp_shm_interface_open() !=
2928 0) // it should be open already, but just in case it isn't...
2929 die("Can not access the NQPTP service. Has it stopped running?");
2930 // clear_ptp_clock();
2931 debug_log_rtsp_message(2, "SETUP \"PTP\" message", req
);
2932 plist_t groupUUID
= plist_dict_get_item(messagePlist
, "groupUUID");
2935 plist_get_string_val(groupUUID
, &gid
);
2937 if (conn
->airplay_gid
)
2938 free(conn
->airplay_gid
);
2939 conn
->airplay_gid
= gid
; // it'll be free'd later on...
2941 debug(1, "Invalid groupUUID");
2944 debug(1, "No groupUUID in SETUP");
2947 // now see if the group contains a group leader
2948 plist_t groupContainsGroupLeader
=
2949 plist_dict_get_item(messagePlist
, "groupContainsGroupLeader");
2950 if (groupContainsGroupLeader
) {
2952 plist_get_bool_val(groupContainsGroupLeader
, &value
);
2953 conn
->groupContainsGroupLeader
= value
;
2954 debug(2, "Updated groupContainsGroupLeader to %u", conn
->groupContainsGroupLeader
);
2956 debug(1, "No groupContainsGroupLeader in SETUP");
2959 char timing_list_message
[4096];
2960 timing_list_message
[0] = 'T';
2961 timing_list_message
[1] = 0;
2963 // ensure the client itself is first -- it's okay if it's duplicated later
2964 strncat(timing_list_message
, " ",
2965 sizeof(timing_list_message
) - 1 - strlen(timing_list_message
));
2966 strncat(timing_list_message
, (const char *)&conn
->client_ip_string
,
2967 sizeof(timing_list_message
) - 1 - strlen(timing_list_message
));
2969 plist_t timing_peer_info
= plist_dict_get_item(messagePlist
, "timingPeerInfo");
2970 if (timing_peer_info
) {
2971 // first, get the incoming plist.
2972 plist_t addresses_array
= plist_dict_get_item(timing_peer_info
, "Addresses");
2973 if (addresses_array
) {
2974 // iterate through the array of items
2975 uint32_t items
= plist_array_get_size(addresses_array
);
2978 for (item
= 0; item
< items
; item
++) {
2979 plist_t n
= plist_array_get_item(addresses_array
, item
);
2980 char *ip_address
= NULL
;
2981 plist_get_string_val(n
, &ip_address
);
2982 // debug(1, "Timing peer: %s", ip_address);
2983 strncat(timing_list_message
, " ",
2984 sizeof(timing_list_message
) - 1 - strlen(timing_list_message
));
2985 strncat(timing_list_message
, ip_address
,
2986 sizeof(timing_list_message
) - 1 - strlen(timing_list_message
));
2990 debug(1, "SETUP on Connection %d: No timingPeerInfo addresses in the array.",
2991 conn
->connection_number
);
2994 debug(1, "SETUP on Connection %d: Can't find timingPeerInfo addresses",
2995 conn
->connection_number
);
2997 // make up the timing peer info list part of the response...
2998 // debug(1,"Create timingPeerInfoPlist");
2999 plist_t timingPeerInfoPlist
= plist_new_dict();
3000 plist_t addresses
= plist_new_array(); // to hold the device's interfaces
3001 plist_array_append_item(addresses
, plist_new_string(conn
->self_ip_string
));
3002 // debug(1,"self ip: \"%s\"", conn->self_ip_string);
3004 struct ifaddrs
*addrs
, *iap
;
3006 for (iap
= addrs
; iap
!= NULL
; iap
= iap
->ifa_next
) {
3007 // debug(1, "Interface index %d, name: \"%s\"",if_nametoindex(iap->ifa_name),
3009 if ((iap
->ifa_addr
) && (iap
->ifa_netmask
) && (iap
->ifa_flags
& IFF_UP
) &&
3010 ((iap
->ifa_flags
& IFF_LOOPBACK
) == 0)) {
3011 char buf
[INET6_ADDRSTRLEN
+ 1]; // +1 for a NUL
3012 memset(buf
, 0, sizeof(buf
));
3013 if (iap
->ifa_addr
->sa_family
== AF_INET6
) {
3014 struct sockaddr_in6
*addr6
= (struct sockaddr_in6
*)(iap
->ifa_addr
);
3015 inet_ntop(AF_INET6
, (void *)&addr6
->sin6_addr
, buf
, sizeof(buf
));
3016 plist_array_append_item(addresses
, plist_new_string(buf
));
3017 // debug(1, "Own address IPv6: %s", buf);
3019 // strncat(timing_list_message, " ",
3020 // sizeof(timing_list_message) - 1 - strlen(timing_list_message));
3021 // strncat(timing_list_message, buf,
3022 // sizeof(timing_list_message) - 1 - strlen(timing_list_message));
3025 struct sockaddr_in
*addr
= (struct sockaddr_in
*)(iap
->ifa_addr
);
3026 inet_ntop(AF_INET
, (void *)&addr
->sin_addr
, buf
, sizeof(buf
));
3027 plist_array_append_item(addresses
, plist_new_string(buf
));
3028 // debug(1, "Own address IPv4: %s", buf);
3030 // strncat(timing_list_message, " ",
3031 // sizeof(timing_list_message) - 1 - strlen(timing_list_message));
3032 // strncat(timing_list_message, buf,
3033 // sizeof(timing_list_message) - 1 - strlen(timing_list_message));
3039 // debug(1,"initial timing peer command: \"%s\".", timing_list_message);
3040 // ptp_send_control_message_string(timing_list_message);
3041 set_client_as_ptp_clock(conn
);
3042 ptp_send_control_message_string(
3043 "B"); // signify clock dependability period is "B"eginning (or continuing)
3044 plist_dict_set_item(timingPeerInfoPlist
, "Addresses", addresses
);
3045 plist_dict_set_item(timingPeerInfoPlist
, "ID",
3046 plist_new_string(conn
->self_ip_string
));
3047 plist_dict_set_item(setupResponsePlist
, "timingPeerInfo", timingPeerInfoPlist
);
3048 // get a port to use as an event port
3049 // bind a new TCP port and get a socket
3050 conn
->local_event_port
= 0; // any port
3051 int err
= bind_socket_and_port(SOCK_STREAM
, conn
->connection_ip_family
,
3052 conn
->self_ip_string
, conn
->self_scope_id
,
3053 &conn
->local_event_port
, &conn
->event_socket
);
3055 die("SETUP on Connection %d: Error %d: could not find a TCP port to use as an "
3058 conn
->connection_number
, err
);
3061 listen(conn
->event_socket
, 128); // ensure socket is open before telling client
3063 debug(2, "Connection %d: TCP PTP event port opened: %u.", conn
->connection_number
,
3064 conn
->local_event_port
);
3066 if (conn
->rtp_event_thread
!= NULL
)
3067 debug(1, "previous rtp_event_thread allocation not freed, it seems.");
3068 conn
->rtp_event_thread
= malloc(sizeof(pthread_t
));
3069 if (conn
->rtp_event_thread
== NULL
)
3070 die("Couldn't allocate space for pthread_t");
3072 pthread_create(conn
->rtp_event_thread
, NULL
, &rtp_event_receiver
, (void *)conn
);
3074 plist_dict_set_item(setupResponsePlist
, "eventPort",
3075 plist_new_uint(conn
->local_event_port
));
3076 plist_dict_set_item(setupResponsePlist
, "timingPort", plist_new_uint(0)); // dummy
3079 cancel_all_RTSP_threads(unspecified_stream_category,
3080 conn->connection_number); // kill all the other
3084 config
.airplay_statusflags
|= 1 << 11; // DeviceSupportsRelay
3085 build_bonjour_strings(conn
);
3086 debug(2, "Connection %d: SETUP mdns_update on %s.", conn
->connection_number
,
3087 get_category_string(conn
->airplay_stream_category
));
3088 mdns_update(NULL
, secondary_txt_records
);
3089 resp
->respcode
= 200;
3091 debug(1, "SETUP on Connection %d: PTP setup -- no timingPeerInfo plist.",
3092 conn
->connection_number
);
3095 #ifdef CONFIG_METADATA
3096 check_and_send_plist_metadata(messagePlist
, "name", 'snam');
3097 check_and_send_plist_metadata(messagePlist
, "deviceID", 'cdid');
3098 check_and_send_plist_metadata(messagePlist
, "model", 'cmod');
3099 check_and_send_plist_metadata(messagePlist
, "macAddress", 'cmac');
3102 // this should never happen!
3103 debug(1, "SETUP on Connection %d: could not become principal conn.",
3104 conn
->connection_number
);
3105 resp
->respcode
= 453;
3107 } else if (conn
->airplay_stream_category
== ntp_stream
) {
3108 debug(1, "SETUP on Connection %d: ntp stream handling is not implemented!",
3109 conn
->connection_number
, req
);
3110 warn("Shairport Sync can not handle NTP streams.");
3111 } else if (conn
->airplay_stream_category
== remote_control_stream
) {
3113 debug_log_rtsp_message(2, "SETUP (no stream) \"isRemoteControlOnly\" message", req);
3115 // get a port to use as an event port
3116 // bind a new TCP port and get a socket
3117 conn->local_event_port = 0; // any port
3118 int err = bind_socket_and_port(SOCK_STREAM, conn->connection_ip_family,
3119 conn->self_ip_string, conn->self_scope_id,
3120 &conn->local_event_port, &conn->event_socket);
3122 die("SETUP on Connection %d: Error %d: could not find a TCP port to use as an event "
3124 conn->connection_number, err);
3127 listen(conn->event_socket, 128); // ensure socket is open before telling client
3129 debug(1, "Connection %d SETUP (RC): TCP Remote Control event port opened: %u.",
3130 conn->connection_number, conn->local_event_port);
3131 if (conn->rtp_event_thread != NULL)
3133 "Connection %d SETUP (RC): previous rtp_event_thread allocation not freed, it "
3135 conn->connection_number);
3137 conn->rtp_event_thread = malloc(sizeof(pthread_t));
3138 if (conn->rtp_event_thread == NULL)
3139 die("Couldn't allocate space for pthread_t");
3140 pthread_create(conn->rtp_event_thread, NULL, &rtp_event_receiver, (void *)conn);
3141 plist_dict_set_item(setupResponsePlist, "eventPort",
3142 plist_new_uint(conn->local_event_port));
3143 plist_dict_set_item(setupResponsePlist, "timingPort", plist_new_uint(0));
3144 cancel_all_RTSP_threads(
3145 remote_control_stream,
3146 conn->connection_number); // kill all the other remote control listeners
3148 resp
->respcode
= 200;
3150 debug(1, "SETUP on Connection %d: an unrecognised \"%s\" setup detected.",
3151 conn
->connection_number
, timingProtocolString
);
3152 warn("Shairport Sync can not handle streams of this type: \"%s\".", timingProtocolString
);
3154 free(timingProtocolString
);
3156 debug(1, "SETUP on Connection %d: Can't retrieve timingProtocol string in initial SETUP.",
3157 conn
->connection_number
);
3161 "SETUP on Connection %d: Unrecognised SETUP incoming message from \"%s\": no "
3162 "timingProtocol or streams plist found.",
3163 conn
->connection_number
, (const char *)conn
->client_ip_string
);
3164 debug_log_rtsp_message(2, "Unrecognised SETUP incoming message.", req
);
3165 warn("Unrecognised SETUP incoming message -- ignored.");
3168 debug(2, "Connection %d: SETUP on %s. A \"streams\" array has been found",
3169 conn
->connection_number
, get_category_string(conn
->airplay_stream_category
));
3170 if (conn
->airplay_stream_category
== ptp_stream
) {
3172 ptp_send_control_message_string(
3173 "B"); // signify clock dependability period is "B"eginning (or continuing)
3174 plist_t stream0
= plist_array_get_item(streams
, 0);
3176 plist_t streams_array
= plist_new_array(); // to hold the ports and stuff
3177 plist_t stream0dict
= plist_new_dict();
3179 // get the session key -- it must have one
3181 plist_t item
= plist_dict_get_item(stream0
, "shk"); // session key
3182 uint64_t item_value
= 0; // the length
3183 plist_get_data_val(item
, (char **)&conn
->session_key
, &item_value
);
3186 // set up a UDP control stream and thread and a UDP or TCP audio stream and thread
3188 // bind a new UDP port and get a socket
3189 conn
->local_ap2_control_port
= 0; // any port
3190 err
= bind_socket_and_port(SOCK_DGRAM
, conn
->connection_ip_family
, conn
->self_ip_string
,
3191 conn
->self_scope_id
, &conn
->local_ap2_control_port
,
3192 &conn
->ap2_control_socket
);
3194 die("Error %d: could not find a UDP port to use as an ap2_control port", err
);
3196 debug(2, "Connection %d: UDP control port opened: %u.", conn
->connection_number
,
3197 conn
->local_ap2_control_port
);
3199 pthread_create(&conn
->rtp_ap2_control_thread
, NULL
, &rtp_ap2_control_receiver
, (void *)conn
);
3201 // get the DACP-ID and Active Remote for remote control stuff
3203 char *ar
= msg_get_header(req
, "Active-Remote");
3205 debug(3, "Connection %d: SETUP AP2 -- Active-Remote string seen: \"%s\".",
3206 conn
->connection_number
, ar
);
3207 // get the active remote
3208 if (conn
->dacp_active_remote
) // this is in case SETUP was previously called
3209 free(conn
->dacp_active_remote
);
3210 conn
->dacp_active_remote
= strdup(ar
);
3211 #ifdef CONFIG_METADATA
3212 send_metadata('ssnc', 'acre', ar
, strlen(ar
), req
, 1);
3215 debug(1, "Connection %d: SETUP AP2 no Active-Remote information the SETUP Record.",
3216 conn
->connection_number
);
3217 if (conn
->dacp_active_remote
) { // this is in case SETUP was previously called
3218 free(conn
->dacp_active_remote
);
3219 conn
->dacp_active_remote
= NULL
;
3223 ar
= msg_get_header(req
, "DACP-ID");
3225 debug(3, "Connection %d: SETUP AP2 -- DACP-ID string seen: \"%s\".",
3226 conn
->connection_number
, ar
);
3227 if (conn
->dacp_id
) // this is in case SETUP was previously called
3228 free(conn
->dacp_id
);
3229 conn
->dacp_id
= strdup(ar
);
3230 #ifdef CONFIG_METADATA
3231 send_metadata('ssnc', 'daid', ar
, strlen(ar
), req
, 1);
3234 debug(1, "Connection %d: SETUP AP2 doesn't include DACP-ID string information.",
3235 conn
->connection_number
);
3236 if (conn
->dacp_id
) { // this is in case SETUP was previously called
3237 free(conn
->dacp_id
);
3238 conn
->dacp_id
= NULL
;
3242 // now, get the type of the stream.
3243 item
= plist_dict_get_item(stream0
, "type");
3245 plist_get_uint_val(item
, &item_value
);
3247 switch (item_value
) {
3249 debug(1, "Connection %d. AP2 Realtime Audio Stream.", conn
->connection_number
);
3250 debug_log_rtsp_message(2, "Realtime Audio Stream SETUP incoming message", req
);
3251 conn
->airplay_stream_type
= realtime_stream
;
3252 // bind a new UDP port and get a socket
3253 conn
->local_realtime_audio_port
= 0; // any port
3254 err
= bind_socket_and_port(SOCK_DGRAM
, conn
->connection_ip_family
, conn
->self_ip_string
,
3255 conn
->self_scope_id
, &conn
->local_realtime_audio_port
,
3256 &conn
->realtime_audio_socket
);
3258 die("Error %d: could not find a UDP port to use as a realtime_audio port", err
);
3260 debug(2, "Connection %d: UDP realtime audio port opened: %u.", conn
->connection_number
,
3261 conn
->local_realtime_audio_port
);
3263 pthread_create(&conn
->rtp_realtime_audio_thread
, NULL
, &rtp_realtime_audio_receiver
,
3266 plist_dict_set_item(stream0dict
, "type", plist_new_uint(96));
3267 plist_dict_set_item(stream0dict
, "dataPort",
3268 plist_new_uint(conn
->local_realtime_audio_port
));
3270 conn
->stream
.type
= ast_apple_lossless
;
3271 debug(3, "An ALAC stream has been detected.");
3273 // Set reasonable connection defaults
3274 conn
->stream
.fmtp
[0] = 96;
3275 conn
->stream
.fmtp
[1] = 352;
3276 conn
->stream
.fmtp
[2] = 0;
3277 conn
->stream
.fmtp
[3] = 16;
3278 conn
->stream
.fmtp
[4] = 40;
3279 conn
->stream
.fmtp
[5] = 10;
3280 conn
->stream
.fmtp
[6] = 14;
3281 conn
->stream
.fmtp
[7] = 2;
3282 conn
->stream
.fmtp
[8] = 255;
3283 conn
->stream
.fmtp
[9] = 0;
3284 conn
->stream
.fmtp
[10] = 0;
3285 conn
->stream
.fmtp
[11] = 44100;
3287 // set the parameters of the player (as distinct from the parameters of the decoder --
3288 // that's done later).
3289 conn
->max_frames_per_packet
= conn
->stream
.fmtp
[1]; // number of audio frames per packet.
3290 conn
->input_rate
= conn
->stream
.fmtp
[11];
3291 conn
->input_num_channels
= conn
->stream
.fmtp
[7];
3292 conn
->input_bit_depth
= conn
->stream
.fmtp
[3];
3293 conn
->input_bytes_per_frame
= conn
->input_num_channels
* ((conn
->input_bit_depth
+ 7) / 8);
3294 debug(2, "Realtime Stream Play");
3295 activity_monitor_signify_activity(1);
3296 player_prepare_to_play(conn
);
3299 conn
->rtp_running
= 1; // hack!
3302 debug(2, "Connection %d. AP2 Buffered Audio Stream.", conn
->connection_number
);
3303 debug_log_rtsp_message(2, "Buffered Audio Stream SETUP incoming message", req
);
3304 conn
->airplay_stream_type
= buffered_stream
;
3307 // bind a new TCP port and get a socket
3308 conn
->local_buffered_audio_port
= 0; // any port
3309 err
= bind_socket_and_port(SOCK_STREAM
, conn
->connection_ip_family
, conn
->self_ip_string
,
3310 conn
->self_scope_id
, &conn
->local_buffered_audio_port
,
3311 &conn
->buffered_audio_socket
);
3313 die("SETUP on Connection %d: Error %d: could not find a TCP port to use as a "
3314 "buffered_audio port",
3315 conn
->connection_number
, err
);
3318 listen(conn
->buffered_audio_socket
, 128); // ensure it's open before telling the client
3320 debug(2, "Connection %d: TCP Buffered Audio port opened: %u.", conn
->connection_number
,
3321 conn
->local_buffered_audio_port
);
3324 conn
->max_frames_per_packet
= 352; // number of audio frames per packet.
3325 conn
->input_rate
= 44100; // we are stuck with this for the moment.
3326 conn
->input_num_channels
= 2;
3327 conn
->input_bit_depth
= 16;
3328 conn
->input_bytes_per_frame
= conn
->input_num_channels
* ((conn
->input_bit_depth
+ 7) / 8);
3329 activity_monitor_signify_activity(1);
3330 player_prepare_to_play(
3331 conn
); // get capabilities of DAC before creating the buffered audio thread
3333 pthread_create(&conn
->rtp_buffered_audio_thread
, NULL
, &rtp_buffered_audio_processor
,
3336 plist_dict_set_item(stream0dict
, "type", plist_new_uint(103));
3337 plist_dict_set_item(stream0dict
, "dataPort",
3338 plist_new_uint(conn
->local_buffered_audio_port
));
3339 plist_dict_set_item(stream0dict
, "audioBufferSize",
3340 plist_new_uint(conn
->ap2_audio_buffer_size
));
3342 // this should be cancelled by an activity_monitor_signify_activity(1)
3343 // call in the SETRATEANCHORI handler, which should come up right away
3344 activity_monitor_signify_activity(0);
3346 conn
->rtp_running
= 1; // hack!
3349 debug(1, "SETUP on Connection %d: Unhandled stream type %" PRIu64
".",
3350 conn
->connection_number
, item_value
);
3351 debug_log_rtsp_message(1, "Unhandled stream type incoming message", req
);
3354 plist_dict_set_item(stream0dict
, "controlPort", plist_new_uint(conn
->local_ap2_control_port
));
3356 plist_array_append_item(streams_array
, stream0dict
);
3357 plist_dict_set_item(setupResponsePlist
, "streams", streams_array
);
3358 resp
->respcode
= 200;
3360 } else if (conn
->airplay_stream_category
== remote_control_stream
) {
3361 debug(2, "Connection %d (RC): SETUP: Remote Control Stream received from %s.",
3362 conn
->connection_number
, conn
->client_ip_string
);
3363 debug_log_rtsp_message(2, "Remote Control Stream SETUP incoming message", req
);
3365 // get a port to use as an data port
3366 // bind a new TCP port and get a socket
3367 conn->local_data_port = 0; // any port
3369 bind_socket_and_port(SOCK_STREAM, conn->connection_ip_family, conn->self_ip_string,
3370 conn->self_scope_id, &conn->local_data_port, &conn->data_socket);
3372 die("SETUP on Connection %d (RC): Error %d: could not find a TCP port to use as a data "
3374 conn->connection_number, err);
3377 debug(1, "Connection %d SETUP (RC): TCP Remote Control data port opened: %u.",
3378 conn->connection_number, conn->local_data_port);
3379 if (conn->rtp_data_thread != NULL)
3380 debug(1, "Connection %d SETUP (RC): previous rtp_data_thread allocation not freed, it
3381 seems.", conn->connection_number); conn->rtp_data_thread = malloc(sizeof(pthread_t)); if
3382 (conn->rtp_data_thread == NULL) die("Couldn't allocate space for pthread_t");
3384 pthread_create(conn->rtp_data_thread, NULL, &rtp_data_receiver, (void *)conn);
3386 plist_t coreResponseDict = plist_new_dict();
3387 plist_dict_set_item(coreResponseDict, "streamID", plist_new_uint(1));
3388 plist_dict_set_item(coreResponseDict, "type", plist_new_uint(130));
3389 plist_dict_set_item(coreResponseDict, "dataPort", plist_new_uint(conn->local_data_port));
3391 plist_t coreResponseArray = plist_new_array();
3392 plist_array_append_item(coreResponseArray, coreResponseDict);
3393 plist_dict_set_item(setupResponsePlist, "streams", coreResponseArray);
3395 resp
->respcode
= 200;
3397 debug(1, "Connection %d: SETUP: Stream received but no airplay category set. Nothing done.",
3398 conn
->connection_number
);
3402 if (resp
->respcode
== 200) {
3403 plist_to_bin(setupResponsePlist
, &resp
->content
, &resp
->contentlength
);
3404 plist_free(setupResponsePlist
);
3405 msg_add_header(resp
, "Content-Type", "application/x-apple-binary-plist");
3407 plist_free(messagePlist
);
3408 if (clientNameString
!= NULL
)
3409 free(clientNameString
);
3410 debug_log_rtsp_message(2, " SETUP response", resp
);
3414 void handle_setup(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
3415 debug(2, "Connection %d: SETUP", conn
->connection_number
);
3416 resp
->respcode
= 451; // invalid arguments -- expect them
3417 // check this connection has the principal_conn, obtained during a prior ANNOUNCE
3418 if ((conn
!= NULL
) && (principal_conn
== conn
)) {
3419 uint16_t cport
, tport
;
3420 char *ar
= msg_get_header(req
, "Active-Remote");
3422 debug(2, "Connection %d: SETUP: Active-Remote string seen: \"%s\".", conn
->connection_number
,
3424 // get the active remote
3425 if (conn
->dacp_active_remote
) // this is in case SETUP was previously called
3426 free(conn
->dacp_active_remote
);
3427 conn
->dacp_active_remote
= strdup(ar
);
3428 #ifdef CONFIG_METADATA
3429 send_metadata('ssnc', 'acre', ar
, strlen(ar
), req
, 1);
3432 debug(2, "Connection %d: SETUP: Note: no Active-Remote information seen.",
3433 conn
->connection_number
);
3434 if (conn
->dacp_active_remote
) { // this is in case SETUP was previously called
3435 free(conn
->dacp_active_remote
);
3436 conn
->dacp_active_remote
= NULL
;
3440 ar
= msg_get_header(req
, "DACP-ID");
3442 debug(2, "Connection %d: SETUP: DACP-ID string seen: \"%s\".", conn
->connection_number
, ar
);
3443 if (conn
->dacp_id
) // this is in case SETUP was previously called
3444 free(conn
->dacp_id
);
3445 conn
->dacp_id
= strdup(ar
);
3446 #ifdef CONFIG_METADATA
3447 send_metadata('ssnc', 'daid', ar
, strlen(ar
), req
, 1);
3450 debug(2, "Connection %d: SETUP doesn't include DACP-ID string information.",
3451 conn
->connection_number
);
3452 if (conn
->dacp_id
) { // this is in case SETUP was previously called
3453 free(conn
->dacp_id
);
3454 conn
->dacp_id
= NULL
;
3458 char *hdr
= msg_get_header(req
, "Transport");
3461 p
= strstr(hdr
, "control_port=");
3463 p
= strchr(p
, '=') + 1;
3466 p
= strstr(hdr
, "timing_port=");
3468 p
= strchr(p
, '=') + 1;
3471 if (conn
->rtp_running
) {
3472 if ((conn
->remote_control_port
!= cport
) || (conn
->remote_timing_port
!= tport
)) {
3473 warn("Connection %d: Duplicate SETUP message with different control (old %u, new %u) "
3475 "timing (old %u, new "
3476 "%u) ports! This is probably fatal!",
3477 conn
->connection_number
, conn
->remote_control_port
, cport
,
3478 conn
->remote_timing_port
, tport
);
3480 warn("Connection %d: Duplicate SETUP message with the same control (%u) and timing "
3483 "probably not fatal.",
3484 conn
->connection_number
, conn
->remote_control_port
, conn
->remote_timing_port
);
3487 rtp_setup(&conn
->local
, &conn
->remote
, cport
, tport
, conn
);
3489 if (conn
->local_audio_port
!= 0) {
3491 char resphdr
[256] = "";
3492 snprintf(resphdr
, sizeof(resphdr
),
3494 "UDP;unicast;interleaved=0-1;mode=record;control_port=%d;"
3495 "timing_port=%d;server_"
3497 conn
->local_control_port
, conn
->local_timing_port
, conn
->local_audio_port
);
3499 msg_add_header(resp
, "Transport", resphdr
);
3501 msg_add_header(resp
, "Session", "1");
3503 resp
->respcode
= 200; // it all worked out okay
3505 "Connection %d: SETUP DACP-ID \"%s\" from %s to %s with UDP ports Control: "
3506 "%d, Timing: %d and Audio: %d.",
3507 conn
->connection_number
, conn
->dacp_id
, &conn
->client_ip_string
,
3508 &conn
->self_ip_string
, conn
->local_control_port
, conn
->local_timing_port
,
3509 conn
->local_audio_port
);
3512 debug(1, "Connection %d: SETUP seems to specify a null audio port.",
3513 conn
->connection_number
);
3516 debug(1, "Connection %d: SETUP doesn't specify a timing_port.", conn
->connection_number
);
3519 debug(1, "Connection %d: SETUP doesn't specify a control_port.", conn
->connection_number
);
3522 debug(1, "Connection %d: SETUP doesn't contain a Transport header.", conn
->connection_number
);
3525 warn("Connection %d SETUP received without having the player (no ANNOUNCE?)",
3526 conn
->connection_number
);
3528 if (resp
->respcode
== 200) {
3529 #ifdef CONFIG_METADATA
3530 send_ssnc_metadata('clip', conn
->client_ip_string
, strlen(conn
->client_ip_string
), 1);
3531 send_ssnc_metadata('svip', conn
->self_ip_string
, strlen(conn
->self_ip_string
), 1);
3534 debug(1, "Connection %d: SETUP error -- releasing the player lock.", conn
->connection_number
);
3535 release_play_lock(conn
);
3540 static void handle_ignore(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
3541 debug(1, "Connection thread %d: IGNORE", conn->connection_number);
3542 resp->respcode = 200;
3546 void handle_set_parameter_parameter(rtsp_conn_info
*conn
, rtsp_message
*req
,
3547 __attribute__((unused
)) rtsp_message
*resp
) {
3549 char *cp
= req
->content
;
3550 int cp_left
= req
->contentlength
;
3555 for (i = 0; i < k; i++)
3556 snprintf((char *)buf + 2 * i, 3, "%02x", cp[i]);
3557 debug(1, "handle_set_parameter_parameter: \"%s\".",buf);
3561 while (cp_left
&& cp
) {
3562 next
= nextline(cp
, cp_left
);
3563 // note: "next" will return NULL if there is no \r or \n or \r\n at the end of this
3564 // but we are always guaranteed that if cp is not null, it will be pointing to something
3568 cp_left
-= (next
- cp
);
3572 if (!strncmp(cp
, "volume: ", strlen("volume: "))) {
3573 float volume
= atof(cp
+ strlen("volume: "));
3574 debug(2, "Connection %d: request to set AirPlay Volume to: %f.", conn
->connection_number
,
3576 // if we are playing, go ahead and change the volume
3577 #ifdef CONFIG_DBUS_INTERFACE
3578 if (dbus_service_is_running()) {
3579 shairport_sync_set_volume(shairportSyncSkeleton
, volume
);
3582 pthread_cleanup_debug_mutex_lock(&principal_conn_lock
, 100000,
3583 1); // don't let the principal_conn be changed
3584 if (principal_conn
== conn
) {
3585 player_volume(volume
, conn
);
3588 conn
->own_airplay_volume
= volume
;
3589 conn
->own_airplay_volume_set
= 1;
3591 pthread_cleanup_pop(1); // release the principal_conn lock
3592 config
.last_access_to_volume_info_time
= get_absolute_time_in_ns();
3593 #ifdef CONFIG_DBUS_INTERFACE
3596 } else if (strncmp(cp
, "progress: ", strlen("progress: ")) ==
3597 0) { // this can be sent even when metadata is not solicited
3599 #ifdef CONFIG_METADATA
3600 char *progress
= cp
+ strlen("progress: ");
3601 // debug(2, "progress: \"%s\"",progress); // rtpstampstart/rtpstampnow/rtpstampend 44100 per
3603 send_ssnc_metadata('prgr', progress
, strlen(progress
), 1);
3607 debug(1, "Connection %d, unrecognised parameter: \"%s\" (%d)\n", conn
->connection_number
, cp
,
3614 #ifdef CONFIG_METADATA
3615 // Metadata is not used by shairport-sync.
3616 // Instead we send all metadata to a fifo pipe, so that other apps can listen to
3617 // the pipe and use the metadata.
3619 // We use two 4-character codes to identify each piece of data and we send the
3620 // data itself, if any,
3623 // The first 4-character code, called the "type", is either:
3624 // 'core' for all the regular metadadata coming from iTunes, etc., or
3625 // 'ssnc' (for 'shairport-sync') for all metadata coming from Shairport Sync
3627 // start/end delimiters, etc.
3629 // For 'core' metadata, the second 4-character code is the 4-character metadata
3632 // For 'ssnc' metadata, the second 4-character code is used to distinguish the
3635 // Cover art is not tagged in the same way as other metadata, it seems, so is
3636 // sent as an 'ssnc' type
3637 // metadata message with the code 'PICT'
3638 // Here are the 'ssnc' codes defined so far:
3639 // 'PICT' -- the payload is a picture, either a JPEG or a PNG. Check the
3640 // first few bytes to see
3642 // 'abeg' -- active mode entered. No arguments
3643 // 'aend' -- active mode exited. No arguments
3644 // 'pbeg' -- play stream begin. No arguments
3645 // 'pend' -- play stream end. No arguments
3646 // 'pfls' -- play stream flush. The argument is an unsigned 32-bit
3647 // frame number. It seems that all frames up to but not
3648 // including this frame are to be flushed.
3650 // 'prsm' -- play stream resume. No arguments. (deprecated)
3651 // 'paus' -- buffered audio stream paused. No arguments.
3652 // 'pres' -- buffered audio stream resumed. No arguments.
3653 // 'pffr' -- the first frame of a play session has been received and has been validly
3655 // 'pvol' -- play volume. The volume is sent as a string --
3656 // "airplay_volume,volume,lowest_volume,highest_volume"
3657 // volume, lowest_volume and highest_volume are given in dB.
3658 // The "airplay_volume" is what's sent to the player, and is from
3659 // 0.00 down to -30.00,
3660 // with -144.00 meaning mute.
3661 // This is linear on the volume control slider of iTunes or iOS
3663 // 'prgr' -- progress -- this is metadata from AirPlay consisting of RTP
3664 // timestamps for the start
3665 // of the current play sequence, the current play point and the end of the
3667 // I guess the timestamps wrap at 2^32.
3668 // 'mdst' -- a sequence of metadata is about to start; will have, as data,
3669 // the rtptime associated with the metadata, if available
3670 // 'mden' -- a sequence of metadata has ended; will have, as data, the
3671 // rtptime associated with the metadata, if available
3672 // 'pcst' -- a picture is about to be sent; will have, as data, the rtptime
3673 // associated with the picture, if available
3674 // 'pcen' -- a picture has been sent; will have, as data, the rtptime
3675 // associated with the metadata, if available
3676 // 'snam' -- A device -- e.g. "Joe's iPhone" -- has opened a play session.
3677 // Specifically, it's the "X-Apple-Client-Name" string
3678 // 'snua' -- A "user agent" -- e.g. "iTunes/12..." -- has opened a play
3679 // session. Specifically, it's the "User-Agent" string
3680 // The next two two tokens are to facilitate remote control of the source.
3681 // There is some information at http://nto.github.io/AirPlay.html about
3682 // remote control of the source.
3684 // 'daid' -- this is the source's DACP-ID (if it has one -- it's not
3685 // guaranteed), useful if you want to remotely control the source. Use this
3686 // string to identify the source's remote control on the network.
3687 // 'acre' -- this is the source's Active-Remote token, necessary if you want
3688 // to send commands to the source's remote control (if it has one).
3689 // `clip` -- the payload is the IP number of the client, i.e. the sender of audio.
3690 // Can be an IPv4 or an IPv6 number. In AirPlay 2 operation, it is sent as soon
3691 // as the client has exclusive access to the player and after any existing
3692 // play session has been interrupted and terminated.
3693 // `conn` -- the payload is the IP number of the client, i.e. the sender of audio.
3694 // Can be an IPv4 or an IPv6 number. This is an AirPlay-2-only message.
3695 // It is sent as soon as the client requests access to the player.
3696 // If Shairport Sync is already playing, this message is sent before the current
3697 // play session is stopped.
3698 // `svip` -- the payload is the IP number of the server, i.e. the player itself.
3699 // Can be an IPv4 or an IPv6 number.
3700 // `svna` -- the payload is the service name of the player, i.e. the name by
3701 // which it is seen in the AirPlay menu.
3702 // `disc` -- the payload is the IP number of the client, i.e. the sender of audio.
3703 // Can be an IPv4 or an IPv6 number. This is an AirPlay-2-only message.
3704 // It is sent when a client has been disconnected.
3705 // `dapo` -- the payload is the port number (as text) on the server to which remote
3706 // control commands should be sent. It is 3689 for iTunes but varies for iOS devices.
3709 // A special sub-protocol is used for sending large data items over UDP
3710 // If the payload exceeded 4 MB, it is chunked using the following format:
3711 // "ssnc", "chnk", packet_ix, packet_counts, packet_tag, packet_type, chunked_data.
3712 // Notice that the number of items is different to the standard
3714 // including a simple base64 encoder to minimise malloc/free activity
3716 // From Stack Overflow, with thanks:
3717 // http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
3718 // minor mods to make independent of C99.
3719 // more significant changes make it not malloc memory
3720 // needs to initialise the docoding table first
3722 // add _so to end of name to avoid confusion with polarssl's implementation
3724 static char encoding_table
[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
3725 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
3726 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
3727 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
3728 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
3730 static size_t mod_table
[] = {0, 2, 1};
3732 // pass in a pointer to the data, its length, a pointer to the output buffer and
3733 // a pointer to an int
3734 // containing its maximum length
3735 // the actual length will be returned.
3737 char *base64_encode_so(const unsigned char *data
, size_t input_length
, char *encoded_data
,
3738 size_t *output_length
) {
3740 size_t calculated_output_length
= 4 * ((input_length
+ 2) / 3);
3741 if (calculated_output_length
> *output_length
)
3743 *output_length
= calculated_output_length
;
3746 for (i
= 0, j
= 0; i
< input_length
;) {
3748 uint32_t octet_a
= i
< input_length
? (unsigned char)data
[i
++] : 0;
3749 uint32_t octet_b
= i
< input_length
? (unsigned char)data
[i
++] : 0;
3750 uint32_t octet_c
= i
< input_length
? (unsigned char)data
[i
++] : 0;
3752 uint32_t triple
= (octet_a
<< 0x10) + (octet_b
<< 0x08) + octet_c
;
3754 encoded_data
[j
++] = encoding_table
[(triple
>> 3 * 6) & 0x3F];
3755 encoded_data
[j
++] = encoding_table
[(triple
>> 2 * 6) & 0x3F];
3756 encoded_data
[j
++] = encoding_table
[(triple
>> 1 * 6) & 0x3F];
3757 encoded_data
[j
++] = encoding_table
[(triple
>> 0 * 6) & 0x3F];
3760 for (i
= 0; i
< mod_table
[input_length
% 3]; i
++)
3761 encoded_data
[*output_length
- 1 - i
] = '=';
3763 return encoded_data
;
3770 // static int dirty = 0;
3772 pc_queue metadata_queue
;
3773 #define metadata_queue_size 500
3774 metadata_package metadata_queue_items
[metadata_queue_size
];
3775 pthread_t metadata_thread
;
3777 #ifdef CONFIG_METADATA_HUB
3778 pc_queue metadata_hub_queue
;
3779 #define metadata_hub_queue_size 500
3780 metadata_package metadata_hub_queue_items
[metadata_hub_queue_size
];
3781 pthread_t metadata_hub_thread
;
3785 pc_queue metadata_mqtt_queue
;
3786 #define metadata_mqtt_queue_size 500
3787 metadata_package metadata_mqtt_queue_items
[metadata_mqtt_queue_size
];
3788 pthread_t metadata_mqtt_thread
;
3791 static int metadata_sock
= -1;
3792 static struct sockaddr_in metadata_sockaddr
;
3793 static char *metadata_sockmsg
;
3794 pc_queue metadata_multicast_queue
;
3795 #define metadata_multicast_queue_size 500
3796 metadata_package metadata_multicast_queue_items
[metadata_queue_size
];
3797 pthread_t metadata_multicast_thread
;
3799 void metadata_create_multicast_socket(void) {
3800 if (config
.metadata_enabled
== 0)
3803 // Unlike metadata pipe, socket is opened once and stays open,
3804 // so we can call it in create
3805 if (config
.metadata_sockaddr
&& config
.metadata_sockport
) {
3806 metadata_sock
= socket(AF_INET
, SOCK_DGRAM
, 0);
3807 if (metadata_sock
< 0) {
3808 debug(1, "Could not open metadata socket");
3810 int buffer_size
= METADATA_SNDBUF
;
3811 setsockopt(metadata_sock
, SOL_SOCKET
, SO_SNDBUF
, &buffer_size
, sizeof(buffer_size
));
3812 bzero((char *)&metadata_sockaddr
, sizeof(metadata_sockaddr
));
3813 metadata_sockaddr
.sin_family
= AF_INET
;
3814 metadata_sockaddr
.sin_addr
.s_addr
= inet_addr(config
.metadata_sockaddr
);
3815 metadata_sockaddr
.sin_port
= htons(config
.metadata_sockport
);
3816 metadata_sockmsg
= malloc(config
.metadata_sockmsglength
);
3817 if (metadata_sockmsg
) {
3818 memset(metadata_sockmsg
, 0, config
.metadata_sockmsglength
);
3820 die("Could not malloc metadata multicast socket buffer");
3826 void metadata_delete_multicast_socket(void) {
3827 if (config
.metadata_enabled
== 0)
3829 shutdown(metadata_sock
, SHUT_RDWR
); // we want to immediately deallocate the buffer
3830 close(metadata_sock
);
3831 if (metadata_sockmsg
)
3832 free(metadata_sockmsg
);
3835 void metadata_open(void) {
3836 if (config
.metadata_enabled
== 0)
3839 size_t pl
= strlen(config
.metadata_pipename
) + 1;
3841 char *path
= malloc(pl
+ 1);
3842 snprintf(path
, pl
+ 1, "%s", config
.metadata_pipename
);
3844 fd
= try_to_open_pipe_for_writing(path
);
3848 static void metadata_close(void) {
3855 void metadata_multicast_process(uint32_t type
, uint32_t code
, char *data
, uint32_t length
) {
3856 // debug(1, "Process multicast metadata with type %x, code %x and length %u.", type, code,
3858 if (metadata_sock
>= 0 && length
< config
.metadata_sockmsglength
- 8) {
3859 char *ptr
= metadata_sockmsg
;
3867 memcpy(ptr
, data
, length
);
3868 sendto(metadata_sock
, metadata_sockmsg
, length
+ 8, 0, (struct sockaddr
*)&metadata_sockaddr
,
3869 sizeof(metadata_sockaddr
));
3870 } else if (metadata_sock
>= 0) {
3871 // send metadata in numbered chunks using the protocol:
3872 // ("ssnc", "chnk", packet_ix, packet_counts, packet_tag, packet_type, chunked_data)
3874 uint32_t chunk_ix
= 0;
3875 if (config
.metadata_sockmsglength
== 24)
3876 die("A divide by zero almost occurred (config.metadata_sockmsglength = 24).");
3877 uint32_t chunk_total
= length
/ (config
.metadata_sockmsglength
- 24);
3878 if (chunk_total
* (config
.metadata_sockmsglength
- 24) < length
) {
3881 uint32_t remaining
= length
;
3883 char *data_crsr
= data
;
3885 char *ptr
= metadata_sockmsg
;
3886 memcpy(ptr
, "ssncchnk", 8);
3888 v
= htonl(chunk_ix
);
3891 v
= htonl(chunk_total
);
3900 size_t datalen
= remaining
;
3901 if (datalen
> config
.metadata_sockmsglength
- 24) {
3902 datalen
= config
.metadata_sockmsglength
- 24;
3904 memcpy(ptr
, data_crsr
, datalen
);
3905 data_crsr
+= datalen
;
3906 sendto(metadata_sock
, metadata_sockmsg
, datalen
+ 24, 0,
3907 (struct sockaddr
*)&metadata_sockaddr
, sizeof(metadata_sockaddr
));
3909 remaining
-= datalen
;
3916 void metadata_process(uint32_t type
, uint32_t code
, char *data
, uint32_t length
) {
3917 // debug(1, "Process metadata with type %x, code %x and length %u.", type, code, length);
3919 // readers may go away and come back
3925 char thestring
[1024];
3926 snprintf(thestring
, 1024, "<item><type>%x</type><code>%x</code><length>%u</length>", type
, code
,
3928 // ret = non_blocking_write(fd, thestring, strlen(thestring));
3929 ret
= write(fd
, thestring
, strlen(thestring
));
3931 // debug(1,"metadata_process error %d exit 1",ret);
3934 if ((data
!= NULL
) && (length
> 0)) {
3935 snprintf(thestring
, 1024, "\n<data encoding=\"base64\">\n");
3936 // ret = non_blocking_write(fd, thestring, strlen(thestring));
3937 ret
= write(fd
, thestring
, strlen(thestring
));
3939 // debug(1,"metadata_process error %d exit 2",ret);
3942 // here, we write the data in base64 form using our nice base64 encoder
3943 // but, we break it into lines of 76 output characters, except for the last
3945 // thus, we send groups of (76/4)*3 = 57 bytes to the encoder at a time
3946 size_t remaining_count
= length
;
3947 char *remaining_data
= data
;
3948 // size_t towrite_count;
3950 while ((remaining_count
) && (ret
>= 0)) {
3951 size_t towrite_count
= remaining_count
;
3952 if (towrite_count
> 57)
3954 size_t outbuf_size
= 76; // size of output buffer on entry, length of result on exit
3955 if (base64_encode_so((unsigned char *)remaining_data
, towrite_count
, outbuf
, &outbuf_size
) ==
3957 debug(1, "Error encoding base64 data.");
3958 // debug(1,"Remaining count: %d ret: %d, outbuf_size:
3959 // %d.",remaining_count,ret,outbuf_size);
3960 // ret = non_blocking_write(fd, outbuf, outbuf_size);
3961 ret
= write(fd
, outbuf
, outbuf_size
);
3963 // debug(1,"metadata_process error %d exit 3",ret);
3966 remaining_data
+= towrite_count
;
3967 remaining_count
-= towrite_count
;
3969 snprintf(thestring
, 1024, "</data>");
3970 // ret = non_blocking_write(fd, thestring, strlen(thestring));
3971 ret
= write(fd
, thestring
, strlen(thestring
));
3973 // debug(1,"metadata_process error %d exit 4",ret);
3977 snprintf(thestring
, 1024, "</item>\n");
3978 // ret = non_blocking_write(fd, thestring, strlen(thestring));
3979 ret
= write(fd
, thestring
, strlen(thestring
));
3981 // debug(1,"metadata_process error %d exit 5",ret);
3986 void metadata_pack_cleanup_function(void *arg
) {
3987 // debug(1, "metadata_pack_cleanup_function called");
3988 metadata_package
*pack
= (metadata_package
*)arg
;
3990 msg_free(&pack
->carrier
); // release the message
3991 else if (pack
->data
)
3993 // debug(1, "metadata_pack_cleanup_function exit");
3996 void metadata_thread_cleanup_function(__attribute__((unused
)) void *arg
) {
3997 // debug(2, "metadata_thread_cleanup_function called");
3999 pc_queue_delete(&metadata_queue
);
4002 void *metadata_thread_function(__attribute__((unused
)) void *ignore
) {
4003 // create a pc_queue for passing information to a threaded metadata handler
4004 pc_queue_init(&metadata_queue
, (char *)&metadata_queue_items
, sizeof(metadata_package
),
4005 metadata_queue_size
, "pipe");
4006 metadata_create_multicast_socket();
4007 metadata_package pack
;
4008 pthread_cleanup_push(metadata_thread_cleanup_function
, NULL
);
4010 pc_queue_get_item(&metadata_queue
, &pack
);
4011 pthread_cleanup_push(metadata_pack_cleanup_function
, (void *)&pack
);
4012 if (config
.metadata_enabled
) {
4014 debug(3, " pipe: type %x, code %x, length %u, message %d.", pack
.type
, pack
.code
,
4015 pack
.length
, pack
.carrier
->index_number
);
4017 debug(3, " pipe: type %x, code %x, length %u.", pack
.type
, pack
.code
, pack
.length
);
4019 metadata_process(pack
.type
, pack
.code
, pack
.data
, pack
.length
);
4020 debug(3, " pipe: done.");
4022 pthread_cleanup_pop(1);
4024 pthread_cleanup_pop(1); // will never happen
4028 void metadata_multicast_thread_cleanup_function(__attribute__((unused
)) void *arg
) {
4029 // debug(2, "metadata_multicast_thread_cleanup_function called");
4030 metadata_delete_multicast_socket();
4031 pc_queue_delete(&metadata_multicast_queue
);
4034 void *metadata_multicast_thread_function(__attribute__((unused
)) void *ignore
) {
4035 // create a pc_queue for passing information to a threaded metadata handler
4036 pc_queue_init(&metadata_multicast_queue
, (char *)&metadata_multicast_queue_items
,
4037 sizeof(metadata_package
), metadata_multicast_queue_size
, "multicast");
4038 metadata_create_multicast_socket();
4039 metadata_package pack
;
4040 pthread_cleanup_push(metadata_multicast_thread_cleanup_function
, NULL
);
4042 pc_queue_get_item(&metadata_multicast_queue
, &pack
);
4043 pthread_cleanup_push(metadata_pack_cleanup_function
, (void *)&pack
);
4044 if (config
.metadata_enabled
) {
4048 "%x, code %x, length %u, message %d.",
4049 pack
.type
, pack
.code
, pack
.length
, pack
.carrier
->index_number
);
4053 "%x, code %x, length %u.",
4054 pack
.type
, pack
.code
, pack
.length
);
4056 metadata_multicast_process(pack
.type
, pack
.code
, pack
.data
, pack
.length
);
4058 " multicast: done.");
4060 pthread_cleanup_pop(1);
4062 pthread_cleanup_pop(1); // will never happen
4066 #ifdef CONFIG_METADATA_HUB
4067 void metadata_hub_close(void) {}
4069 void metadata_hub_thread_cleanup_function(__attribute__((unused
)) void *arg
) {
4070 // debug(2, "metadata_hub_thread_cleanup_function called");
4071 metadata_hub_close();
4072 pc_queue_delete(&metadata_hub_queue
);
4075 void *metadata_hub_thread_function(__attribute__((unused
)) void *ignore
) {
4076 // create a pc_queue for passing information to a threaded metadata handler
4077 pc_queue_init(&metadata_hub_queue
, (char *)&metadata_hub_queue_items
, sizeof(metadata_package
),
4078 metadata_hub_queue_size
, "hub");
4079 metadata_package pack
;
4080 pthread_cleanup_push(metadata_hub_thread_cleanup_function
, NULL
);
4082 pc_queue_get_item(&metadata_hub_queue
, &pack
);
4083 pthread_cleanup_push(metadata_pack_cleanup_function
, (void *)&pack
);
4085 debug(3, " hub: type %x, code %x, length %u, message %d.", pack
.type
,
4086 pack
.code
, pack
.length
, pack
.carrier
->index_number
);
4088 debug(3, " hub: type %x, code %x, length %u.", pack
.type
, pack
.code
,
4091 metadata_hub_process_metadata(pack
.type
, pack
.code
, pack
.data
, pack
.length
);
4092 debug(3, " hub: done.");
4093 pthread_cleanup_pop(1);
4095 pthread_cleanup_pop(1); // will never happen
4101 void metadata_mqtt_close(void) {}
4103 void metadata_mqtt_thread_cleanup_function(__attribute__((unused
)) void *arg
) {
4104 // debug(2, "metadata_mqtt_thread_cleanup_function called");
4105 metadata_mqtt_close();
4106 pc_queue_delete(&metadata_mqtt_queue
);
4107 // debug(2, "metadata_mqtt_thread_cleanup_function done");
4110 void *metadata_mqtt_thread_function(__attribute__((unused
)) void *ignore
) {
4111 // create a pc_queue for passing information to a threaded metadata handler
4112 pc_queue_init(&metadata_mqtt_queue
, (char *)&metadata_mqtt_queue_items
, sizeof(metadata_package
),
4113 metadata_mqtt_queue_size
, "mqtt");
4114 metadata_package pack
;
4115 pthread_cleanup_push(metadata_mqtt_thread_cleanup_function
, NULL
);
4117 pc_queue_get_item(&metadata_mqtt_queue
, &pack
);
4118 pthread_cleanup_push(metadata_pack_cleanup_function
, (void *)&pack
);
4119 if (config
.mqtt_enabled
) {
4122 " mqtt: type %x, code %x, length %u, message "
4124 pack
.type
, pack
.code
, pack
.length
, pack
.carrier
->index_number
);
4126 debug(3, " mqtt: type %x, code %x, length %u.",
4127 pack
.type
, pack
.code
, pack
.length
);
4129 mqtt_process_metadata(pack
.type
, pack
.code
, pack
.data
, pack
.length
);
4130 debug(3, " mqtt: done.");
4133 pthread_cleanup_pop(1);
4135 pthread_cleanup_pop(1); // will never happen
4140 void metadata_init(void) {
4141 if (config
.metadata_enabled
) {
4142 // create the metadata pipe, if necessary
4143 size_t pl
= strlen(config
.metadata_pipename
) + 1;
4144 char *path
= malloc(pl
+ 1);
4145 snprintf(path
, pl
+ 1, "%s", config
.metadata_pipename
);
4146 mode_t oldumask
= umask(000);
4147 if (mkfifo(path
, 0666) && errno
!= EEXIST
)
4148 die("Could not create metadata pipe \"%s\".", path
);
4150 debug(1, "metadata pipe name is \"%s\".", path
);
4153 fd
= try_to_open_pipe_for_writing(path
);
4154 // we check that it's not a "real" error. From the "man 2 open" page:
4155 // "ENXIO O_NONBLOCK | O_WRONLY is set, the named file is a FIFO, and no process has the FIFO
4156 // open for reading." Which is okay.
4157 if ((fd
== -1) && (errno
!= ENXIO
)) {
4158 char errorstring
[1024];
4159 strerror_r(errno
, (char *)errorstring
, sizeof(errorstring
));
4160 debug(1, "metadata_hub_thread_function -- error %d (\"%s\") opening pipe: \"%s\".", errno
,
4161 (char *)errorstring
, path
);
4162 warn("can not open metadata pipe -- error %d (\"%s\") opening pipe: \"%s\".", errno
,
4163 (char *)errorstring
, path
);
4166 if (pthread_create(&metadata_thread
, NULL
, metadata_thread_function
, NULL
) != 0)
4167 debug(1, "Failed to create metadata thread!");
4169 if (pthread_create(&metadata_multicast_thread
, NULL
, metadata_multicast_thread_function
,
4171 debug(1, "Failed to create metadata multicast thread!");
4173 #ifdef CONFIG_METADATA_HUB
4174 if (pthread_create(&metadata_hub_thread
, NULL
, metadata_hub_thread_function
, NULL
) != 0)
4175 debug(1, "Failed to create metadata hub thread!");
4178 if (pthread_create(&metadata_mqtt_thread
, NULL
, metadata_mqtt_thread_function
, NULL
) != 0)
4179 debug(1, "Failed to create metadata mqtt thread!");
4181 metadata_running
= 1;
4184 void metadata_stop(void) {
4185 if (metadata_running
) {
4186 debug(2, "metadata_stop called.");
4188 // debug(2, "metadata stop mqtt thread.");
4189 pthread_cancel(metadata_mqtt_thread
);
4190 pthread_join(metadata_mqtt_thread
, NULL
);
4191 // debug(2, "metadata stop mqtt done.");
4193 #ifdef CONFIG_METADATA_HUB
4194 // debug(2, "metadata stop hub thread.");
4195 pthread_cancel(metadata_hub_thread
);
4196 pthread_join(metadata_hub_thread
, NULL
);
4197 // debug(2, "metadata stop hub done.");
4199 if (config
.metadata_enabled
) {
4200 // debug(2, "metadata stop multicast thread.");
4201 if (metadata_multicast_thread
) {
4202 pthread_cancel(metadata_multicast_thread
);
4203 pthread_join(metadata_multicast_thread
, NULL
);
4204 // debug(2, "metadata stop multicast done.");
4206 if (metadata_thread
) {
4207 // debug(2, "metadata stop metadata_thread thread.");
4208 pthread_cancel(metadata_thread
);
4209 pthread_join(metadata_thread
, NULL
);
4210 // debug(2, "metadata_stop finished successfully.");
4216 int send_metadata_to_queue(pc_queue
*queue
, uint32_t type
, uint32_t code
, char *data
,
4217 uint32_t length
, rtsp_message
*carrier
, int block
) {
4223 // pointer to data or NULL,
4224 // length of data or NULL,
4225 // the rtsp_message or NULL,
4227 // the rtsp_message is sent for 'core' messages, because it contains the data
4228 // and must not be freed until the data has been read.
4229 // So, it is passed to send_metadata to be retained, sent to the thread where metadata
4230 // is processed and released (and probably freed).
4232 // The rtsp_message is also sent for certain non-'core' messages.
4234 // The reading of the parameters is a bit complex:
4235 // If the rtsp_message field is non-null, then it represents an rtsp_message
4236 // and the data pointer is assumed to point to something within it.
4237 // The reference counter of the rtsp_message is incremented here and
4238 // should be decremented by the metadata handler when finished.
4239 // If the reference count reduces to zero, the message will be freed.
4241 // If the rtsp_message is NULL, then if the pointer is non-null then the data it
4242 // points to, of the length specified, is memcpy'd and passed to the metadata
4243 // handler. The handler should free it when done.
4245 // If the rtsp_message is NULL and the pointer is also NULL, nothing further
4249 metadata_package pack
;
4252 pack
.length
= length
;
4253 pack
.carrier
= carrier
;
4256 msg_retain(pack
.carrier
);
4259 pack
.data
= memdup(data
, length
); // only if it's not a null
4261 int rc
= pc_queue_add_item(queue
, &pack
, block
);
4264 if (rc
== EWOULDBLOCK
)
4266 "metadata queue \"%s\" full, dropping message item: type %x, code %x, data %x, "
4267 "length %u, message %d.",
4268 queue
->name
, pack
.type
, pack
.code
, pack
.data
, pack
.length
,
4269 pack
.carrier
->index_number
);
4270 msg_free(&pack
.carrier
);
4272 if (rc
== EWOULDBLOCK
)
4275 "metadata queue \"%s\" full, dropping data item: type %x, code %x, data %x, length %u.",
4276 queue
->name
, pack
.type
, pack
.code
, pack
.data
, pack
.length
);
4284 int send_metadata(uint32_t type
, uint32_t code
, char *data
, uint32_t length
, rtsp_message
*carrier
,
4287 if (config
.metadata_enabled
) {
4288 rc
= send_metadata_to_queue(&metadata_queue
, type
, code
, data
, length
, carrier
, block
);
4290 send_metadata_to_queue(&metadata_multicast_queue
, type
, code
, data
, length
, carrier
, block
);
4293 #ifdef CONFIG_METADATA_HUB
4294 rc
= send_metadata_to_queue(&metadata_hub_queue
, type
, code
, data
, length
, carrier
, block
);
4298 rc
= send_metadata_to_queue(&metadata_mqtt_queue
, type
, code
, data
, length
, carrier
, block
);
4304 static void handle_set_parameter_metadata(__attribute__((unused
)) rtsp_conn_info
*conn
,
4306 __attribute__((unused
)) rtsp_message
*resp
) {
4307 char *cp
= req
->content
;
4308 unsigned int cl
= req
->contentlength
;
4310 unsigned int off
= 8;
4314 // pick up the metadata tag as an unsigned longint
4315 memcpy(&itag
, (uint32_t *)(cp
+ off
), sizeof(uint32_t)); /* can be misaligned, thus memcpy */
4317 off
+= sizeof(uint32_t);
4319 // pick up the length of the data
4320 memcpy(&vl
, (uint32_t *)(cp
+ off
), sizeof(uint32_t)); /* can be misaligned, thus memcpy */
4322 off
+= sizeof(uint32_t);
4324 // pass the data over
4326 send_metadata('core', itag
, NULL
, 0, NULL
, 1);
4328 send_metadata('core', itag
, (char *)(cp
+ off
), vl
, req
, 1);
4330 // move on to the next item
4337 static void handle_get_parameter(__attribute__((unused
)) rtsp_conn_info
*conn
, rtsp_message
*req
,
4338 rtsp_message
*resp
) {
4339 // debug(1, "Connection %d: GET_PARAMETER", conn->connection_number);
4340 // debug_print_msg_headers(1,req);
4341 // debug_print_msg_content(1,req);
4343 if ((req
->content
) && (req
->contentlength
== strlen("volume\r\n")) &&
4344 strstr(req
->content
, "volume") == req
->content
) {
4345 debug(2, "Connection %d: current volume (%.6f) requested", conn
->connection_number
,
4346 suggested_volume(conn
));
4348 char *p
= malloc(128); // will be automatically deallocated with the response is deleted
4351 resp
->contentlength
= snprintf(p
, 128, "\r\nvolume: %.6f\r\n", suggested_volume(conn
));
4353 debug(1, "Couldn't allocate space for a response.");
4356 resp
->respcode
= 200;
4359 static void handle_set_parameter(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
4360 debug(3, "Connection %d: SET_PARAMETER", conn
->connection_number
);
4361 // if (!req->contentlength)
4362 // debug(1, "received empty SET_PARAMETER request.");
4364 // debug_print_msg_headers(1,req);
4366 char *ct
= msg_get_header(req
, "Content-Type");
4369 // debug(2, "SET_PARAMETER Content-Type:\"%s\".", ct);
4371 #ifdef CONFIG_METADATA
4372 // It seems that the rtptime of the message is used as a kind of an ID that
4374 // to link items of metadata, including pictures, that refer to the same
4376 // If they refer to the same item, they have the same rtptime.
4377 // So we send the rtptime before and after both the metadata items and the
4381 char *hdr
= msg_get_header(req
, "RTP-Info");
4384 p
= strstr(hdr
, "rtptime=");
4390 // not all items have RTP-time stuff in them, which is okay
4392 if (!strncmp(ct
, "application/x-dmap-tagged", 25)) {
4393 debug(3, "received metadata tags in SET_PARAMETER request.");
4395 debug(1, "Missing RTP-Time info for metadata");
4397 send_metadata('ssnc', 'mdst', p
+ 1, strlen(p
+ 1), req
, 1); // metadata starting
4399 send_metadata('ssnc', 'mdst', NULL
, 0, NULL
,
4400 0); // metadata starting, if rtptime is not available
4402 handle_set_parameter_metadata(conn
, req
, resp
);
4405 send_metadata('ssnc', 'mden', p
+ 1, strlen(p
+ 1), req
, 1); // metadata ending
4407 send_metadata('ssnc', 'mden', NULL
, 0, NULL
,
4408 0); // metadata starting, if rtptime is not available
4410 } else if (!strncmp(ct
, "image", 5)) {
4411 // Some server simply ignore the md field from the TXT record. If The
4412 // config says 'please, do not include any cover art', we are polite and
4413 // do not write them to the pipe.
4414 if (config
.get_coverart
) {
4415 // debug(1, "received image in SET_PARAMETER request.");
4416 // note: the image/type tag isn't reliable, so it's not being sent
4417 // -- best look at the first few bytes of the image
4419 debug(1, "Missing RTP-Time info for picture item");
4421 send_metadata('ssnc', 'pcst', p
+ 1, strlen(p
+ 1), req
, 1); // picture starting
4423 send_metadata('ssnc', 'pcst', NULL
, 0, NULL
,
4424 0); // picture starting, if rtptime is not available
4426 send_metadata('ssnc', 'PICT', req
->content
, req
->contentlength
, req
, 1);
4429 send_metadata('ssnc', 'pcen', p
+ 1, strlen(p
+ 1), req
, 1); // picture ending
4431 send_metadata('ssnc', 'pcen', NULL
, 0, NULL
,
4432 0); // picture ending, if rtptime is not available
4434 debug(1, "Ignore received picture item (include_cover_art = no).");
4438 if (!strncmp(ct
, "text/parameters", 15)) {
4439 // debug(2, "received parameters in SET_PARAMETER request.");
4440 handle_set_parameter_parameter(conn
, req
, resp
); // this could be volume or progress
4442 debug(1, "Connection %d: received unknown Content-Type \"%s\" in SET_PARAMETER request.",
4443 conn
->connection_number
, ct
);
4444 debug_print_msg_headers(1, req
);
4447 debug(1, "Connection %d: missing Content-Type header in SET_PARAMETER request.",
4448 conn
->connection_number
);
4450 resp
->respcode
= 200;
4453 static void handle_announce(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
) {
4454 debug(2, "Connection %d: ANNOUNCE", conn
->connection_number
);
4456 int get_play_status
= get_play_lock(conn
, config
.allow_session_interruption
);
4457 if (get_play_status
!= -1) {
4458 debug(2, "Connection %d: ANNOUNCE has acquired play lock.", conn
->connection_number
);
4460 conn
->airplay_stream_category
= classic_airplay_stream
;
4462 // now, if this new session did not break in, then it's okay to reset the next UDP ports
4463 // to the start of the range
4465 if (get_play_status
== 0) { // will be zero if it wasn't waiting to break in
4471 char *cp = req->content;
4472 int cp_left = req->contentlength;
4473 while (cp_left > 1) {
4474 if (strlen(cp) != 0)
4475 debug(1,">>>>>> %s", cp);
4476 cp += strlen(cp) + 1;
4477 cp_left -= strlen(cp) + 1;
4481 // In AirPlay 2, an ANNOUNCE signifies the start of an AirPlay 1 session.
4482 #ifdef CONFIG_AIRPLAY_2
4483 conn
->airplay_type
= ap_1
;
4484 conn
->timing_type
= ts_ntp
;
4485 debug(2, "Connection %d: Classic AirPlay connection from %s:%u to self at %s:%u.",
4486 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
4487 conn
->self_ip_string
, conn
->self_rtsp_port
);
4490 conn
->stream
.type
= ast_unknown
;
4491 resp
->respcode
= 200; // presumed OK
4493 char *paesiv
= NULL
;
4494 char *prsaaeskey
= NULL
;
4496 char *pminlatency
= NULL
;
4497 char *pmaxlatency
= NULL
;
4498 // char *pAudioMediaInfo = NULL;
4499 char *pUncompressedCDAudio
= NULL
;
4500 char *cp
= req
->content
;
4501 int cp_left
= req
->contentlength
;
4503 while (cp_left
&& cp
) {
4504 next
= nextline(cp
, cp_left
);
4505 cp_left
-= next
- cp
;
4507 if (!strncmp(cp
, "a=rtpmap:96 L16/44100/2", strlen("a=rtpmap:96 L16/44100/2")))
4508 pUncompressedCDAudio
= cp
+ strlen("a=rtpmap:96 L16/44100/2");
4510 // if (!strncmp(cp, "m=audio", strlen("m=audio")))
4511 // pAudioMediaInfo = cp + strlen("m=audio");
4513 if (!strncmp(cp
, "o=iTunes", strlen("o=iTunes")))
4514 pssid
= cp
+ strlen("o=iTunes");
4516 if (!strncmp(cp
, "a=fmtp:", strlen("a=fmtp:")))
4517 pfmtp
= cp
+ strlen("a=fmtp:");
4519 if (!strncmp(cp
, "a=aesiv:", strlen("a=aesiv:")))
4520 paesiv
= cp
+ strlen("a=aesiv:");
4522 if (!strncmp(cp
, "a=rsaaeskey:", strlen("a=rsaaeskey:")))
4523 prsaaeskey
= cp
+ strlen("a=rsaaeskey:");
4525 if (!strncmp(cp
, "a=min-latency:", strlen("a=min-latency:")))
4526 pminlatency
= cp
+ strlen("a=min-latency:");
4528 if (!strncmp(cp
, "a=max-latency:", strlen("a=max-latency:")))
4529 pmaxlatency
= cp
+ strlen("a=max-latency:");
4534 if (pUncompressedCDAudio
) {
4535 debug(2, "An uncompressed PCM stream has been detected.");
4536 conn
->stream
.type
= ast_uncompressed
;
4537 conn
->max_frames_per_packet
= 352; // number of audio frames per packet.
4538 conn
->input_rate
= 44100;
4539 conn
->input_num_channels
= 2;
4540 conn
->input_bit_depth
= 16;
4541 conn
->input_bytes_per_frame
= conn
->input_num_channels
* ((conn
->input_bit_depth
+ 7) / 8);
4544 int y = strlen(pAudioMediaInfo);
4549 char *p = pAudioMediaInfo;
4552 for (obfc = 0; obfc < y; obfc++) {
4553 snprintf(obfp, 3, "%02X", (unsigned int)*p);
4558 debug(1, "AudioMediaInfo: \"%s\".", obf);
4564 uint32_t ssid
= uatoi(pssid
);
4565 debug(3, "Synchronisation Source Identifier: %08X,%u", ssid
, ssid
);
4569 conn
->minimum_latency
= atoi(pminlatency
);
4570 debug(3, "Minimum latency %d specified", conn
->minimum_latency
);
4574 conn
->maximum_latency
= atoi(pmaxlatency
);
4575 debug(3, "Maximum latency %d specified", conn
->maximum_latency
);
4578 if ((paesiv
== NULL
) && (prsaaeskey
== NULL
)) {
4579 // debug(1,"Unencrypted session requested?");
4580 conn
->stream
.encrypted
= 0;
4581 } else if ((paesiv
!= NULL
) && (prsaaeskey
!= NULL
)) {
4582 conn
->stream
.encrypted
= 1;
4583 // debug(1,"Encrypted session requested");
4585 warn("Invalid Announce message -- missing paesiv or prsaaeskey.");
4586 resp
->respcode
= 456; // 456 - Header Field Not Valid for Resource
4589 if (conn
->stream
.encrypted
) {
4591 uint8_t *aesiv
= base64_dec(paesiv
, &len
);
4593 memcpy(conn
->stream
.aesiv
, aesiv
, 16);
4595 resp
->respcode
= 456; // 456 - Header Field Not Valid for Resource
4596 warn("client announced aeskey of %d bytes, wanted 16", len
);
4600 uint8_t *rsaaeskey
= base64_dec(prsaaeskey
, &len
);
4601 uint8_t *aeskey
= rsa_apply(rsaaeskey
, len
, &keylen
, RSA_MODE_KEY
);
4604 memcpy(conn
->stream
.aeskey
, aeskey
, 16);
4606 resp
->respcode
= 456; // 456 - Header Field Not Valid for Resource
4607 warn("client announced rsaaeskey of %d bytes, wanted 16", keylen
);
4613 conn
->stream
.type
= ast_apple_lossless
;
4614 debug(3, "An ALAC stream has been detected.");
4616 // Set reasonable connection defaults
4617 conn
->stream
.fmtp
[0] = 96;
4618 conn
->stream
.fmtp
[1] = 352;
4619 conn
->stream
.fmtp
[2] = 0;
4620 conn
->stream
.fmtp
[3] = 16;
4621 conn
->stream
.fmtp
[4] = 40;
4622 conn
->stream
.fmtp
[5] = 10;
4623 conn
->stream
.fmtp
[6] = 14;
4624 conn
->stream
.fmtp
[7] = 2;
4625 conn
->stream
.fmtp
[8] = 255;
4626 conn
->stream
.fmtp
[9] = 0;
4627 conn
->stream
.fmtp
[10] = 0;
4628 conn
->stream
.fmtp
[11] = 44100;
4631 unsigned int max_param
= sizeof(conn
->stream
.fmtp
) / sizeof(conn
->stream
.fmtp
[0]);
4633 while ((found
= strsep(&pfmtp
, " \t")) != NULL
&& i
< max_param
) {
4634 conn
->stream
.fmtp
[i
++] = atoi(found
);
4636 // here we should check the sanity of the fmtp values
4637 // for (i = 0; i < sizeof(conn->stream.fmtp) / sizeof(conn->stream.fmtp[0]); i++)
4638 // debug(1," fmtp[%2d] is: %10d",i,conn->stream.fmtp[i]);
4640 // set the parameters of the player (as distinct from the parameters of the decoder -- that's
4642 conn
->max_frames_per_packet
= conn
->stream
.fmtp
[1]; // number of audio frames per packet.
4643 conn
->input_rate
= conn
->stream
.fmtp
[11];
4644 conn
->input_num_channels
= conn
->stream
.fmtp
[7];
4645 conn
->input_bit_depth
= conn
->stream
.fmtp
[3];
4646 conn
->input_bytes_per_frame
= conn
->input_num_channels
* ((conn
->input_bit_depth
+ 7) / 8);
4649 if ((resp
->respcode
== 200) && (conn
->stream
.type
!= ast_unknown
)) {
4650 char *hdr
= msg_get_header(req
, "X-Apple-Client-Name");
4652 debug(1, "Play connection from device named \"%s\" on RTSP conversation thread %d.", hdr
,
4653 conn
->connection_number
);
4654 #ifdef CONFIG_METADATA
4655 send_metadata('ssnc', 'snam', hdr
, strlen(hdr
), req
, 1);
4658 hdr
= msg_get_header(req
, "User-Agent");
4660 conn
->UserAgent
= strdup(hdr
);
4661 debug(2, "Play connection from user agent \"%s\" on RTSP conversation thread %d.", hdr
,
4662 conn
->connection_number
);
4663 // if the user agent is AirPlay and has a version number of 353 or less (from iOS 11.1,2)
4664 // use the older way of calculating the latency
4666 char *p
= strstr(hdr
, "AirPlay");
4670 conn
->AirPlayVersion
= atoi(p
+ 1);
4671 debug(2, "AirPlay version %d detected.", conn
->AirPlayVersion
);
4675 #ifdef CONFIG_METADATA
4676 send_metadata('ssnc', 'snua', hdr
, strlen(hdr
), req
, 1);
4680 warn("Can not process the following ANNOUNCE message:");
4681 // print each line of the request content
4682 // the problem is that nextline has replace all returns, newlines, etc. by
4684 char *cp
= req
->content
;
4685 int cp_left
= req
->contentlength
;
4686 while (cp_left
> 1) {
4687 if (strlen(cp
) != 0)
4689 cp
+= strlen(cp
) + 1;
4690 cp_left
-= strlen(cp
) + 1;
4693 debug(2, "Connection %d: ANNOUNCE has completed.", conn
->connection_number
);
4695 // can't get the principal_conn
4696 resp
->respcode
= 453;
4700 #ifdef CONFIG_AIRPLAY_2
4701 static struct method_handler
{
4703 void (*ap1_handler
)(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
); // for AirPlay 1
4704 void (*ap2_handler
)(rtsp_conn_info
*conn
, rtsp_message
*req
, rtsp_message
*resp
); // for AirPlay 2
4705 } method_handlers
[] = {{"OPTIONS", handle_options
, handle_options
},
4706 {"ANNOUNCE", handle_announce
, handle_announce
},
4707 {"FLUSH", handle_flush
, handle_flush
},
4708 {"TEARDOWN", handle_teardown
, handle_teardown_2
},
4709 {"SETUP", handle_setup
, handle_setup_2
},
4710 {"GET_PARAMETER", handle_get_parameter
, handle_get_parameter
},
4711 {"SET_PARAMETER", handle_set_parameter
, handle_set_parameter
},
4712 {"RECORD", handle_record
, handle_record_2
},
4713 {"GET", handle_get
, handle_get
},
4714 {"POST", handle_post
, handle_post
},
4715 {"SETPEERS", handle_unimplemented_ap1
, handle_setpeers
},
4716 {"SETRATEANCHORTI", handle_unimplemented_ap1
, handle_setrateanchori
},
4717 {"FLUSHBUFFERED", handle_unimplemented_ap1
, handle_flushbuffered
},
4718 {"SETRATE", handle_unimplemented_ap1
, handle_setrate
},
4719 {NULL
, NULL
, NULL
}};
4721 static struct method_handler
{
4723 void (*handler
)(rtsp_conn_info
*conn
, rtsp_message
*req
,
4724 rtsp_message
*resp
); // for AirPlay 1 only
4725 } method_handlers
[] = {{"OPTIONS", handle_options
},
4726 {"GET", handle_get
},
4727 {"POST", handle_post
},
4728 {"ANNOUNCE", handle_announce
},
4729 {"FLUSH", handle_flush
},
4730 {"TEARDOWN", handle_teardown
},
4731 {"SETUP", handle_setup
},
4732 {"GET_PARAMETER", handle_get_parameter
},
4733 {"SET_PARAMETER", handle_set_parameter
},
4734 {"RECORD", handle_record
},
4738 static void apple_challenge(int fd
, rtsp_message
*req
, rtsp_message
*resp
) {
4739 char *hdr
= msg_get_header(req
, "Apple-Challenge");
4743 socklen_t sa_len
= sizeof(fdsa
);
4744 getsockname(fd
, (struct sockaddr
*)&fdsa
, &sa_len
);
4747 uint8_t *chall
= base64_dec(hdr
, &chall_len
);
4749 die("null chall in apple_challenge");
4750 uint8_t buf
[48], *bp
= buf
;
4752 memset(buf
, 0, sizeof(buf
));
4754 if (chall_len
> 16) {
4755 warn("oversized Apple-Challenge!");
4759 memcpy(bp
, chall
, chall_len
);
4764 if (fdsa
.SAFAMILY
== AF_INET6
) {
4765 struct sockaddr_in6
*sa6
= (struct sockaddr_in6
*)(&fdsa
);
4766 memcpy(bp
, sa6
->sin6_addr
.s6_addr
, 16);
4771 struct sockaddr_in
*sa
= (struct sockaddr_in
*)(&fdsa
);
4772 memcpy(bp
, &sa
->sin_addr
.s_addr
, 4);
4776 for (i
= 0; i
< 6; i
++)
4777 *bp
++ = config
.ap1_prefix
[i
];
4779 int buflen
, resplen
;
4784 uint8_t *challresp
= rsa_apply(buf
, buflen
, &resplen
, RSA_MODE_AUTH
);
4785 char *encoded
= base64_enc(challresp
, resplen
);
4786 if (encoded
== NULL
)
4787 die("could not allocate memory for \"encoded\"");
4788 // strip the padding.
4789 char *padding
= strchr(encoded
, '=');
4793 msg_add_header(resp
, "Apple-Response", encoded
); // will be freed when the response is freed.
4798 static char *make_nonce(void) {
4800 int fd
= open("/dev/urandom", O_RDONLY
);
4802 die("could not open /dev/urandom!");
4804 if (read(fd
, random
, sizeof(random
)) != sizeof(random
))
4805 debug(1, "Error reading /dev/urandom");
4807 return base64_enc(random
, 8); // returns a pointer to malloc'ed memory
4810 static int rtsp_auth(char **nonce
, rtsp_message
*req
, rtsp_message
*resp
) {
4812 if (!config
.password
)
4815 *nonce
= make_nonce();
4819 char *hdr
= msg_get_header(req
, "Authorization");
4820 if (!hdr
|| strncmp(hdr
, "Digest ", 7))
4823 char *realm
= strstr(hdr
, "realm=\"");
4824 char *username
= strstr(hdr
, "username=\"");
4825 char *response
= strstr(hdr
, "response=\"");
4826 char *uri
= strstr(hdr
, "uri=\"");
4828 if (!realm
|| !username
|| !response
|| !uri
)
4832 realm
= strchr(realm
, '"') + 1;
4833 if (!(quote
= strchr(realm
, '"')))
4836 username
= strchr(username
, '"') + 1;
4837 if (!(quote
= strchr(username
, '"')))
4840 response
= strchr(response
, '"') + 1;
4841 if (!(quote
= strchr(response
, '"')))
4844 uri
= strchr(uri
, '"') + 1;
4845 if (!(quote
= strchr(uri
, '"')))
4849 uint8_t digest_urp
[16], digest_mu
[16], digest_total
[16];
4851 #ifdef CONFIG_OPENSSL
4853 unsigned int digest_urp_len
= EVP_MD_size(EVP_md5());
4854 unsigned int digest_mu_len
= EVP_MD_size(EVP_md5());
4856 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &oldState
);
4857 ctx
= EVP_MD_CTX_new();
4858 EVP_DigestInit_ex(ctx
, EVP_md5(), NULL
);
4860 EVP_DigestUpdate(ctx
, username
, strlen(username
));
4861 EVP_DigestUpdate(ctx
, ":", 1);
4862 EVP_DigestUpdate(ctx
, realm
, strlen(realm
));
4863 EVP_DigestUpdate(ctx
, ":", 1);
4864 EVP_DigestUpdate(ctx
, config
.password
, strlen(config
.password
));
4865 EVP_DigestFinal_ex(ctx
, digest_urp
, &digest_urp_len
);
4866 EVP_MD_CTX_free(ctx
);
4868 ctx
= EVP_MD_CTX_new();
4869 EVP_DigestInit_ex(ctx
, EVP_md5(), NULL
);
4871 EVP_DigestUpdate(ctx
, req
->method
, strlen(req
->method
));
4872 EVP_DigestUpdate(ctx
, ":", 1);
4873 EVP_DigestUpdate(ctx
, uri
, strlen(uri
));
4875 EVP_DigestFinal_ex(ctx
, digest_mu
, &digest_mu_len
);
4876 EVP_MD_CTX_free(ctx
);
4877 pthread_setcancelstate(oldState
, NULL
);
4880 #ifdef CONFIG_MBEDTLS
4881 #if MBEDTLS_VERSION_MINOR >= 7
4882 mbedtls_md5_context tctx
;
4883 mbedtls_md5_starts_ret(&tctx
);
4884 mbedtls_md5_update_ret(&tctx
, (const unsigned char *)username
, strlen(username
));
4885 mbedtls_md5_update_ret(&tctx
, (unsigned char *)":", 1);
4886 mbedtls_md5_update_ret(&tctx
, (const unsigned char *)realm
, strlen(realm
));
4887 mbedtls_md5_update_ret(&tctx
, (unsigned char *)":", 1);
4888 mbedtls_md5_update_ret(&tctx
, (const unsigned char *)config
.password
, strlen(config
.password
));
4889 mbedtls_md5_finish_ret(&tctx
, digest_urp
);
4890 mbedtls_md5_starts_ret(&tctx
);
4891 mbedtls_md5_update_ret(&tctx
, (const unsigned char *)req
->method
, strlen(req
->method
));
4892 mbedtls_md5_update_ret(&tctx
, (unsigned char *)":", 1);
4893 mbedtls_md5_update_ret(&tctx
, (const unsigned char *)uri
, strlen(uri
));
4894 mbedtls_md5_finish_ret(&tctx
, digest_mu
);
4896 mbedtls_md5_context tctx
;
4897 mbedtls_md5_starts(&tctx
);
4898 mbedtls_md5_update(&tctx
, (const unsigned char *)username
, strlen(username
));
4899 mbedtls_md5_update(&tctx
, (unsigned char *)":", 1);
4900 mbedtls_md5_update(&tctx
, (const unsigned char *)realm
, strlen(realm
));
4901 mbedtls_md5_update(&tctx
, (unsigned char *)":", 1);
4902 mbedtls_md5_update(&tctx
, (const unsigned char *)config
.password
, strlen(config
.password
));
4903 mbedtls_md5_finish(&tctx
, digest_urp
);
4904 mbedtls_md5_starts(&tctx
);
4905 mbedtls_md5_update(&tctx
, (const unsigned char *)req
->method
, strlen(req
->method
));
4906 mbedtls_md5_update(&tctx
, (unsigned char *)":", 1);
4907 mbedtls_md5_update(&tctx
, (const unsigned char *)uri
, strlen(uri
));
4908 mbedtls_md5_finish(&tctx
, digest_mu
);
4912 #ifdef CONFIG_POLARSSL
4915 md5_update(&tctx
, (const unsigned char *)username
, strlen(username
));
4916 md5_update(&tctx
, (unsigned char *)":", 1);
4917 md5_update(&tctx
, (const unsigned char *)realm
, strlen(realm
));
4918 md5_update(&tctx
, (unsigned char *)":", 1);
4919 md5_update(&tctx
, (const unsigned char *)config
.password
, strlen(config
.password
));
4920 md5_finish(&tctx
, digest_urp
);
4922 md5_update(&tctx
, (const unsigned char *)req
->method
, strlen(req
->method
));
4923 md5_update(&tctx
, (unsigned char *)":", 1);
4924 md5_update(&tctx
, (const unsigned char *)uri
, strlen(uri
));
4925 md5_finish(&tctx
, digest_mu
);
4929 unsigned char buf
[33];
4930 for (i
= 0; i
< 16; i
++)
4931 snprintf((char *)buf
+ 2 * i
, 3, "%02x", digest_urp
[i
]);
4933 #ifdef CONFIG_OPENSSL
4934 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &oldState
);
4935 unsigned int digest_total_len
= EVP_MD_size(EVP_md5());
4937 ctx
= EVP_MD_CTX_new();
4938 EVP_DigestInit_ex(ctx
, EVP_md5(), NULL
);
4940 EVP_DigestUpdate(ctx
, buf
, 32);
4941 EVP_DigestUpdate(ctx
, ":", 1);
4942 EVP_DigestUpdate(ctx
, *nonce
, strlen(*nonce
));
4943 EVP_DigestUpdate(ctx
, ":", 1);
4944 for (i
= 0; i
< 16; i
++)
4945 snprintf((char *)buf
+ 2 * i
, 3, "%02x", digest_mu
[i
]);
4946 EVP_DigestUpdate(ctx
, buf
, 32);
4947 EVP_DigestFinal_ex(ctx
, digest_total
, &digest_total_len
);
4948 EVP_MD_CTX_free(ctx
);
4949 pthread_setcancelstate(oldState
, NULL
);
4952 #ifdef CONFIG_MBEDTLS
4953 #if MBEDTLS_VERSION_MINOR >= 7
4954 mbedtls_md5_starts_ret(&tctx
);
4955 mbedtls_md5_update_ret(&tctx
, buf
, 32);
4956 mbedtls_md5_update_ret(&tctx
, (unsigned char *)":", 1);
4957 mbedtls_md5_update_ret(&tctx
, (const unsigned char *)*nonce
, strlen(*nonce
));
4958 mbedtls_md5_update_ret(&tctx
, (unsigned char *)":", 1);
4959 for (i
= 0; i
< 16; i
++)
4960 snprintf((char *)buf
+ 2 * i
, 3, "%02x", digest_mu
[i
]);
4961 mbedtls_md5_update_ret(&tctx
, buf
, 32);
4962 mbedtls_md5_finish_ret(&tctx
, digest_total
);
4964 mbedtls_md5_starts(&tctx
);
4965 mbedtls_md5_update(&tctx
, buf
, 32);
4966 mbedtls_md5_update(&tctx
, (unsigned char *)":", 1);
4967 mbedtls_md5_update(&tctx
, (const unsigned char *)*nonce
, strlen(*nonce
));
4968 mbedtls_md5_update(&tctx
, (unsigned char *)":", 1);
4969 for (i
= 0; i
< 16; i
++)
4970 snprintf((char *)buf
+ 2 * i
, 3, "%02x", digest_mu
[i
]);
4971 mbedtls_md5_update(&tctx
, buf
, 32);
4972 mbedtls_md5_finish(&tctx
, digest_total
);
4976 #ifdef CONFIG_POLARSSL
4978 md5_update(&tctx
, buf
, 32);
4979 md5_update(&tctx
, (unsigned char *)":", 1);
4980 md5_update(&tctx
, (const unsigned char *)*nonce
, strlen(*nonce
));
4981 md5_update(&tctx
, (unsigned char *)":", 1);
4982 for (i
= 0; i
< 16; i
++)
4983 snprintf((char *)buf
+ 2 * i
, 3, "%02x", digest_mu
[i
]);
4984 md5_update(&tctx
, buf
, 32);
4985 md5_finish(&tctx
, digest_total
);
4988 for (i
= 0; i
< 16; i
++)
4989 snprintf((char *)buf
+ 2 * i
, 3, "%02x", digest_total
[i
]);
4991 if (!strcmp(response
, (const char *)buf
))
4993 warn("Password authorization failed.");
4996 resp
->respcode
= 401;
4997 int hdrlen
= strlen(*nonce
) + 40;
4998 char *authhdr
= malloc(hdrlen
);
4999 snprintf(authhdr
, hdrlen
, "Digest realm=\"raop\", nonce=\"%s\"", *nonce
);
5000 msg_add_header(resp
, "WWW-Authenticate", authhdr
);
5005 void rtsp_conversation_thread_cleanup_function(void *arg
) {
5006 rtsp_conn_info
*conn
= (rtsp_conn_info
*)arg
;
5009 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &oldState
);
5011 debug(2, "Connection %d: %s rtsp_conversation_thread_func_cleanup_function called.",
5012 conn
->connection_number
, get_category_string(conn
->airplay_stream_category
));
5013 #ifdef CONFIG_AIRPLAY_2
5015 teardown_phase_one(conn
);
5016 teardown_phase_two(conn
);
5022 debug(3, "Connection %d: terminating -- closing timing, control and audio sockets...",
5023 conn
->connection_number
);
5024 if (conn
->control_socket
) {
5025 debug(3, "Connection %d: terminating -- closing control_socket %d.", conn
->connection_number
,
5026 conn
->control_socket
);
5027 close(conn
->control_socket
);
5028 conn
->control_socket
= 0;
5030 if (conn
->timing_socket
) {
5031 debug(3, "Connection %d: terminating -- closing timing_socket %d.", conn
->connection_number
,
5032 conn
->timing_socket
);
5033 close(conn
->timing_socket
);
5034 conn
->timing_socket
= 0;
5036 if (conn
->audio_socket
) {
5037 debug(3, "Connection %d: terminating -- closing audio_socket %d.", conn
->connection_number
,
5038 conn
->audio_socket
);
5039 close(conn
->audio_socket
);
5040 conn
->audio_socket
= 0;
5045 "Connection %d: terminating -- closing RTSP connection socket %d: from %s:%u to self at "
5047 conn
->connection_number
, conn
->fd
, conn
->client_ip_string
, conn
->client_rtsp_port
,
5048 conn
->self_ip_string
, conn
->self_rtsp_port
);
5052 if (conn
->auth_nonce
) {
5053 free(conn
->auth_nonce
);
5054 conn
->auth_nonce
= NULL
;
5057 #ifdef CONFIG_AIRPLAY_2
5058 buf_drain(&conn
->ap2_pairing_context
.control_cipher_bundle
.plaintext_read_buffer
, -1);
5059 buf_drain(&conn
->ap2_pairing_context
.control_cipher_bundle
.encrypted_read_buffer
, -1);
5060 pair_cipher_free(conn
->ap2_pairing_context
.control_cipher_bundle
.cipher_ctx
);
5061 pair_setup_free(conn
->ap2_pairing_context
.setup_ctx
);
5062 pair_verify_free(conn
->ap2_pairing_context
.verify_ctx
);
5063 if (conn
->airplay_gid
) {
5064 free(conn
->airplay_gid
);
5065 conn
->airplay_gid
= NULL
;
5070 rtp_terminate(conn
);
5072 if (conn
->dacp_id
) {
5073 free(conn
->dacp_id
);
5074 conn
->dacp_id
= NULL
;
5077 if (conn
->UserAgent
) {
5078 free(conn
->UserAgent
);
5079 conn
->UserAgent
= NULL
;
5082 // remove flow control and mutexes
5084 int rc
= pthread_mutex_destroy(&conn
->player_create_delete_mutex
);
5086 debug(1, "Connection %d: error %d destroying player_create_delete_mutex.",
5087 conn
->connection_number
, rc
);
5088 rc
= pthread_mutex_destroy(&conn
->volume_control_mutex
);
5090 debug(1, "Connection %d: error %d destroying volume_control_mutex.", conn
->connection_number
,
5092 rc
= pthread_cond_destroy(&conn
->flowcontrol
);
5094 debug(1, "Connection %d: error %d destroying flow control condition variable.",
5095 conn
->connection_number
, rc
);
5096 rc
= pthread_mutex_destroy(&conn
->ab_mutex
);
5098 debug(1, "Connection %d: error %d destroying ab_mutex.", conn
->connection_number
, rc
);
5099 rc
= pthread_mutex_destroy(&conn
->flush_mutex
);
5101 debug(1, "Connection %d: error %d destroying flush_mutex.", conn
->connection_number
, rc
);
5103 debug(3, "Cancel watchdog thread.");
5104 pthread_cancel(conn
->player_watchdog_thread
);
5105 debug(3, "Join watchdog thread.");
5106 pthread_join(conn
->player_watchdog_thread
, NULL
);
5107 debug(3, "Delete watchdog mutex.");
5108 pthread_mutex_destroy(&conn
->watchdog_mutex
);
5110 debug(2, "Connection %d: Closed.", conn
->connection_number
);
5112 pthread_setcancelstate(oldState
, NULL
);
5116 void msg_cleanup_function(void *arg
) {
5117 // debug(3, "msg_cleanup_function called.");
5118 msg_free((rtsp_message
**)arg
);
5121 static void *rtsp_conversation_thread_func(void *pconn
) {
5122 rtsp_conn_info
*conn
= pconn
;
5124 // create the watchdog mutex, initialise the watchdog time and start the watchdog thread;
5125 conn
->watchdog_bark_time
= get_absolute_time_in_ns();
5126 pthread_mutex_init(&conn
->watchdog_mutex
, NULL
);
5127 pthread_create(&conn
->player_watchdog_thread
, NULL
, &player_watchdog_thread_code
, (void *)conn
);
5129 int rc
= pthread_mutex_init(&conn
->flush_mutex
, NULL
);
5131 die("Connection %d: error %d initialising flush_mutex.", conn
->connection_number
, rc
);
5132 rc
= pthread_mutex_init(&conn
->ab_mutex
, NULL
);
5134 die("Connection %d: error %d initialising ab_mutex.", conn
->connection_number
, rc
);
5135 rc
= pthread_cond_init(&conn
->flowcontrol
, NULL
);
5137 die("Connection %d: error %d initialising flow control condition variable.",
5138 conn
->connection_number
, rc
);
5139 rc
= pthread_mutex_init(&conn
->volume_control_mutex
, NULL
);
5141 die("Connection %d: error %d initialising volume_control_mutex.", conn
->connection_number
, rc
);
5143 rc
= pthread_mutex_init(&conn
->player_create_delete_mutex
, NULL
);
5145 die("Connection %d: error %d initialising player_create_delete_mutex.", conn
->connection_number
,
5148 // nothing before this is cancellable
5149 pthread_cleanup_push(rtsp_conversation_thread_cleanup_function
, (void *)conn
);
5151 rtp_initialise(conn
);
5154 enum rtsp_read_request_response reply
;
5156 int rtsp_read_request_attempt_count
= 1; // 1 means exit immediately
5157 rtsp_message
*req
, *resp
;
5159 #ifdef CONFIG_AIRPLAY_2
5160 conn
->ap2_audio_buffer_size
= 1024 * 1024 * 8;
5163 while (conn
->stop
== 0) {
5164 int debug_level
= 2; // for printing the request and response
5165 reply
= rtsp_read_request(conn
, &req
);
5166 if (reply
== rtsp_read_request_response_ok
) {
5167 pthread_cleanup_push(msg_cleanup_function
, (void *)&req
);
5169 pthread_cleanup_push(msg_cleanup_function
, (void *)&resp
);
5170 resp
->respcode
= 501; // Not Implemented
5171 int dl
= debug_level
;
5172 // if ((strcmp(req->method, "OPTIONS") == 0) ||
5173 // (strcmp(req->method, "POST") ==
5174 // 0)) // the options message is very common, so don't log it until level 3
5177 if (conn
->airplay_stream_category
== remote_control_stream
) {
5178 debug(dl
, "Connection %d (RC): Received an RTSP Packet of type \"%s\":",
5179 conn
->connection_number
, req
->method
),
5180 debug_log_rtsp_message(dl
, NULL
, req
);
5182 debug(dl
, "Connection %d: Received an RTSP Packet of type \"%s\":", conn
->connection_number
,
5184 debug_log_rtsp_message(dl
, NULL
, req
);
5186 apple_challenge(conn
->fd
, req
, resp
);
5187 hdr
= msg_get_header(req
, "CSeq");
5189 msg_add_header(resp
, "CSeq", hdr
);
5190 // msg_add_header(resp, "Audio-Jack-Status", "connected; type=analog");
5191 #ifdef CONFIG_AIRPLAY_2
5192 msg_add_header(resp
, "Server", "AirTunes/366.0");
5194 msg_add_header(resp
, "Server", "AirTunes/105.1");
5197 if ((conn
->authorized
== 1) || (rtsp_auth(&conn
->auth_nonce
, req
, resp
)) == 0) {
5198 conn
->authorized
= 1; // it must have been authorized or didn't need a password
5199 struct method_handler
*mh
;
5200 int method_selected
= 0;
5201 for (mh
= method_handlers
; mh
->method
; mh
++) {
5202 if (!strcmp(mh
->method
, req
->method
)) {
5203 method_selected
= 1;
5204 #ifdef CONFIG_AIRPLAY_2
5205 if (conn
->airplay_type
== ap_1
)
5206 mh
->ap1_handler(conn
, req
, resp
);
5208 mh
->ap2_handler(conn
, req
, resp
);
5210 mh
->handler(conn
, req
, resp
);
5215 if (method_selected
== 0) {
5217 "Connection %d: Unrecognised and unhandled rtsp request \"%s\". HTTP Response Code "
5218 "501 (\"Not Implemented\") returned.",
5219 conn
->connection_number
, req
->method
);
5221 int y
= req
->contentlength
;
5226 char *p
= req
->content
;
5229 for (obfc
= 0; obfc
< y
; obfc
++) {
5230 snprintf(obfp
, 3, "%02X", (unsigned int)*p
);
5235 debug(2, "Content: \"%s\".", obf
);
5239 if (conn
->airplay_stream_category
== remote_control_stream
) {
5240 debug(dl
, "Connection %d (RC): RTSP Response:", conn
->connection_number
);
5241 debug_log_rtsp_message(dl
, NULL
, resp
);
5243 debug(dl
, "Connection %d: RTSP Response:", conn
->connection_number
);
5244 debug_log_rtsp_message(dl
, NULL
, resp
);
5246 // if (conn->stop == 0) {
5247 int err
= msg_write_response(conn
, resp
);
5250 "Connection %d: Unable to write an RTSP message response. Terminating the "
5252 conn
->connection_number
);
5253 struct linger so_linger
;
5254 so_linger
.l_onoff
= 1; // "true"
5255 so_linger
.l_linger
= 0;
5256 err
= setsockopt(conn
->fd
, SOL_SOCKET
, SO_LINGER
, &so_linger
, sizeof so_linger
);
5258 debug(1, "Could not set the RTSP socket to abort due to a write error on closing.");
5260 pthread_cancel(conn
->thread
);
5263 pthread_cleanup_pop(1);
5264 pthread_cleanup_pop(1);
5267 if (reply
== rtsp_read_request_response_immediate_shutdown_requested
)
5269 else if ((reply
== rtsp_read_request_response_channel_closed
) ||
5270 (reply
== rtsp_read_request_response_read_error
)) {
5271 if (conn
->player_thread
) {
5272 rtsp_read_request_attempt_count
--;
5273 if (rtsp_read_request_attempt_count
== 0) {
5275 if (reply
== rtsp_read_request_response_read_error
) {
5276 struct linger so_linger
;
5277 so_linger
.l_onoff
= 1; // "true"
5278 so_linger
.l_linger
= 0;
5279 int err
= setsockopt(conn
->fd
, SOL_SOCKET
, SO_LINGER
, &so_linger
, sizeof so_linger
);
5281 debug(1, "Could not set the RTSP socket to abort due to a read error on closing.");
5283 // debuglev = 3; // see what happens next
5285 if (reply
== rtsp_read_request_response_channel_closed
)
5287 "Connection %d: RTSP channel unexpectedly closed -- will try again %d time(s).",
5288 conn
->connection_number
, rtsp_read_request_attempt_count
);
5289 if (reply
== rtsp_read_request_response_read_error
)
5290 debug(2, "Connection %d: RTSP channel read error -- will try again %d time(s).",
5291 conn
->connection_number
, rtsp_read_request_attempt_count
);
5297 } else if (reply
== rtsp_read_request_response_bad_packet
) {
5298 char *response_text
= "RTSP/1.0 400 Bad Request\r\nServer: AirTunes/105.1\r\n\r\n";
5299 ssize_t reply
= write(conn
->fd
, response_text
, strlen(response_text
));
5301 char errorstring
[1024];
5302 strerror_r(errno
, (char *)errorstring
, sizeof(errorstring
));
5303 debug(1, "rtsp_read_request_response_bad_packet write response error %d: \"%s\".", errno
,
5304 (char *)errorstring
);
5305 } else if (reply
!= (ssize_t
)strlen(response_text
)) {
5306 debug(1, "rtsp_read_request_response_bad_packet write %d bytes requested but %d written.",
5307 strlen(response_text
), reply
);
5310 debug(1, "Connection %d: rtsp_read_request error %d, packet ignored.",
5311 conn
->connection_number
, (int)reply
);
5314 debug(3, "Connection %d: Terminate RTSP connection.", conn
->connection_number
);
5319 pthread_cleanup_pop(1);
5320 debug(2, "Connection %d: RTSP thread exit.", conn
->connection_number
);
5325 // this function is not thread safe.
5326 static const char *format_address(struct sockaddr *fsa) {
5327 static char string[INETx_ADDRSTRLEN];
5330 if (fsa->sa_family == AF_INET6) {
5331 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)(fsa);
5332 addr = &(sa6->sin6_addr);
5336 struct sockaddr_in *sa = (struct sockaddr_in *)(fsa);
5337 addr = &(sa->sin_addr);
5339 return inet_ntop(fsa->sa_family, addr, string, sizeof(string));
5343 void rtsp_listen_loop_cleanup_handler(__attribute__((unused
)) void *arg
) {
5345 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &oldState
);
5346 debug(2, "rtsp_listen_loop_cleanup_handler called.");
5347 cancel_all_RTSP_threads(unspecified_stream_category
, 0); // kill all RTSP listeners
5348 int *sockfd
= (int *)arg
;
5351 for (i
= 1; i
<= sockfd
[0]; i
++) {
5352 debug(2, "closing socket %d.", sockfd
[i
]);
5357 pthread_setcancelstate(oldState
, NULL
);
5360 void *rtsp_listen_loop(__attribute((unused
)) void *arg
) {
5362 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &oldState
);
5363 struct addrinfo hints
, *info
, *p
;
5369 principal_conn
= NULL
; // the data structure representing the connection that has the player.
5371 memset(&hints
, 0, sizeof(hints
));
5372 hints
.ai_family
= AF_UNSPEC
;
5373 hints
.ai_socktype
= SOCK_STREAM
;
5374 hints
.ai_flags
= AI_PASSIVE
;
5376 snprintf(portstr
, 6, "%d", config
.port
);
5378 // debug(1,"listen socket port request is \"%s\".",portstr);
5380 ret
= getaddrinfo(NULL
, portstr
, &hints
, &info
);
5382 die("getaddrinfo failed: %s", gai_strerror(ret
));
5385 for (p
= info
; p
; p
= p
->ai_next
) {
5387 int fd
= socket(p
->ai_family
, p
->ai_socktype
, IPPROTO_TCP
);
5390 // Handle socket open failures if protocol unavailable (or IPV6 not handled)
5392 // Set the RTSP socket to close on exec() of child processes
5393 // otherwise background run_this_before_play_begins or run_this_after_play_ends commands
5394 // that are sleeping prevent the daemon from being restarted because
5395 // the listening RTSP port is still in use.
5396 // See: https://github.com/mikebrady/shairport-sync/issues/329
5397 fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
5398 ret
= setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &yes
, sizeof(yes
));
5401 tv
.tv_sec
= 3; // three seconds write timeout
5403 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, (const char *)&tv
, sizeof tv
) == -1)
5404 debug(1, "Error %d setting send timeout for rtsp writeback.", errno
);
5406 if ((config
.dont_check_timeout
== 0) && (config
.timeout
!= 0)) {
5407 tv
.tv_sec
= config
.timeout
; // 120 seconds read timeout by default.
5409 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVTIMEO
, (const char *)&tv
, sizeof tv
) == -1)
5410 debug(1, "Error %d setting read timeout for rtsp connection.", errno
);
5413 // some systems don't support v4 access on v6 sockets, but some do.
5414 // since we need to account for two sockets we might as well
5416 if (p
->ai_family
== AF_INET6
) {
5417 ret
|= setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &yes
, sizeof(yes
));
5422 ret
= bind(fd
, p
->ai_addr
, p
->ai_addrlen
);
5424 // one of the address families will fail on some systems that
5425 // report its availability. do not complain.
5430 if (p
->ai_family
== AF_INET6
) {
5435 debug(1, "unable to listen on %s port %d. The error is: \"%s\".", family
, config
.port
,
5440 sockfd
= realloc(sockfd
, (nsock
+ 1) * sizeof(int));
5442 sockfd
[0] = nsock
; // the first entry is the number of sockets in the array
5449 sockfd = realloc(sockfd, nsock * sizeof(int));
5450 sockfd[nsock - 1] = fd;
5460 // skip the first element in sockfd -- it's the count
5461 for (i
= 1; i
<= nsock
; i
++) {
5462 if (sockfd
[i
] > maxfd
)
5466 char **t1
= txt_records
; // ap1 test records
5467 char **t2
= NULL
; // possibly two text records
5468 #ifdef CONFIG_AIRPLAY_2
5469 // make up a secondary set of text records
5470 t2
= secondary_txt_records
; // second set of text records in AirPlay 2 only
5472 build_bonjour_strings(NULL
); // no conn yet
5473 mdns_register(t1
, t2
); // note that the dacp thread could still be using the mdns stuff after
5474 // all player threads have been terminated, so mdns_unregister can't be
5475 // in the rtsp_listen_loop cleanup.
5477 pthread_setcancelstate(oldState
, NULL
);
5480 pthread_cleanup_push(rtsp_listen_loop_cleanup_handler
, (void *)sockfd
);
5482 pthread_testcancel();
5486 // skip the first element in sockfd -- it's the count
5487 for (i
= 1; i
<= nsock
; i
++)
5488 FD_SET(sockfd
[i
], &fds
);
5490 ret
= select(maxfd
+ 1, &fds
, 0, 0, &tv
);
5501 // skip the first element in sockfd -- it's the count
5502 for (i
= 1; i
<= nsock
; i
++) {
5503 if (FD_ISSET(sockfd
[i
], &fds
)) {
5504 acceptfd
= sockfd
[i
];
5508 if (acceptfd
< 0) // timeout
5511 rtsp_conn_info
*conn
= malloc(sizeof(rtsp_conn_info
));
5513 die("Couldn't allocate memory for an rtsp_conn_info record.");
5514 memset(conn
, 0, sizeof(rtsp_conn_info
));
5515 conn
->connection_number
= RTSP_connection_index
++;
5516 #ifdef CONFIG_AIRPLAY_2
5517 conn
->airplay_type
= ap_2
; // changed if an ANNOUNCE is received
5518 conn
->timing_type
= ts_ptp
; // changed if an ANNOUNCE is received
5521 socklen_t size_of_reply
= sizeof(SOCKADDR
);
5522 conn
->fd
= accept(acceptfd
, (struct sockaddr
*)&conn
->remote
, &size_of_reply
);
5524 debug(1, "Connection %d: New connection on port %d not accepted:", conn
->connection_number
,
5526 perror("failed to accept connection");
5529 size_of_reply
= sizeof(SOCKADDR
);
5530 if (getsockname(conn
->fd
, (struct sockaddr
*)&conn
->local
, &size_of_reply
) == 0) {
5532 // Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
5534 // turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
5535 // before giving up an ETIMEOUT error is returned if the keepalive check fails
5537 int keepAliveIdleTime
= 35; // wait this many seconds before checking for a dropped client
5538 int keepAliveCount
= 5; // check this many times
5539 int keepAliveInterval
= 5; // wait this many seconds between checks
5541 #if defined COMPILE_FOR_BSD || defined COMPILE_FOR_OSX
5542 #define SOL_OPTION IPPROTO_TCP
5544 #define SOL_OPTION SOL_TCP
5547 #ifdef COMPILE_FOR_OSX
5548 #define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPALIVE
5550 #define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPIDLE
5553 if (setsockopt(conn
->fd
, SOL_OPTION
, KEEP_ALIVE_OR_IDLE_OPTION
,
5554 (void *)&keepAliveIdleTime
, sizeof(keepAliveIdleTime
))) {
5555 debug(1, "can't set the keepidle wait time");
5558 if (setsockopt(conn
->fd
, SOL_OPTION
, TCP_KEEPCNT
, (void *)&keepAliveCount
,
5559 sizeof(keepAliveCount
))) {
5560 debug(1, "can't set the keepidle missing count");
5562 if (setsockopt(conn
->fd
, SOL_OPTION
, TCP_KEEPINTVL
, (void *)&keepAliveInterval
,
5563 sizeof(keepAliveInterval
))) {
5564 debug(1, "can't set the keepidle missing count interval");
5567 // initialise the connection info
5568 void *client_addr
= NULL
, *self_addr
= NULL
;
5569 conn
->connection_ip_family
= conn
->local
.SAFAMILY
;
5572 if (conn
->connection_ip_family
== AF_INET6
) {
5573 struct sockaddr_in6
*sa6
= (struct sockaddr_in6
*)&conn
->remote
;
5574 client_addr
= &(sa6
->sin6_addr
);
5575 conn
->client_rtsp_port
= ntohs(sa6
->sin6_port
);
5577 sa6
= (struct sockaddr_in6
*)&conn
->local
;
5578 self_addr
= &(sa6
->sin6_addr
);
5579 conn
->self_rtsp_port
= ntohs(sa6
->sin6_port
);
5580 conn
->self_scope_id
= sa6
->sin6_scope_id
;
5583 if (conn
->connection_ip_family
== AF_INET
) {
5584 struct sockaddr_in
*sa4
= (struct sockaddr_in
*)&conn
->remote
;
5585 client_addr
= &(sa4
->sin_addr
);
5586 conn
->client_rtsp_port
= ntohs(sa4
->sin_port
);
5588 sa4
= (struct sockaddr_in
*)&conn
->local
;
5589 self_addr
= &(sa4
->sin_addr
);
5590 conn
->self_rtsp_port
= ntohs(sa4
->sin_port
);
5593 inet_ntop(conn
->connection_ip_family
, client_addr
, conn
->client_ip_string
,
5594 sizeof(conn
->client_ip_string
));
5595 inet_ntop(conn
->connection_ip_family
, self_addr
, conn
->self_ip_string
,
5596 sizeof(conn
->self_ip_string
));
5598 debug(2, "Connection %d: New connection from %s:%u to self at %s:%u.",
5599 conn
->connection_number
, conn
->client_ip_string
, conn
->client_rtsp_port
,
5600 conn
->self_ip_string
, conn
->self_rtsp_port
);
5601 conn
->connection_start_time
= get_absolute_time_in_ns();
5603 debug(1, "Error figuring out Shairport Sync's own IP number.");
5606 ret
= pthread_create(&conn
->thread
, NULL
, rtsp_conversation_thread_func
,
5607 conn
); // also acts as a memory barrier
5609 char errorstring
[1024];
5610 strerror_r(ret
, (char *)errorstring
, sizeof(errorstring
));
5611 die("Connection %d: cannot create an RTSP conversation thread. Error %d: \"%s\".",
5612 conn
->connection_number
, ret
, (char *)errorstring
);
5614 debug(3, "Successfully created RTSP receiver thread %d.", conn
->connection_number
);
5615 conn
->running
= 1; // this must happen before the thread is tracked
5619 pthread_cleanup_pop(1); // should never happen
5621 warn("could not establish a service on port %d -- program terminating. Is another instance of "
5622 "Shairport Sync running on this device?",
5625 debug(1, "Oops -- fell out of the RTSP select loop");