diff --git a/lib/raop.c b/lib/raop.c index d783786..ba585c9 100755 --- a/lib/raop.c +++ b/lib/raop.c @@ -207,19 +207,48 @@ conn_request(void *ptr, http_request_t *request, http_response_t **response) { logger_log(conn->raop->logger, LOGGER_WARNING, "RAOP not initialized at FLUSH"); } } else if (!strcmp(method, "TEARDOWN")) { + /* get the teardown request type(s): (type 96, 110, or none) */ + const char *data; + int data_len; + bool teardown_96 = false, teardown_110 = false; + data = http_request_get_data(request, &data_len); + plist_t req_root_node = NULL; + plist_from_bin(data, data_len, &req_root_node); + char * plist_xml; + uint32_t plist_len; + plist_to_xml(req_root_node, &plist_xml, &plist_len); + logger_log(conn->raop->logger, LOGGER_DEBUG, "%s", plist_xml); + free(plist_xml); + plist_t req_streams_node = plist_dict_get_item(req_root_node, "streams"); + /* Process stream teardown requests */ + if (PLIST_IS_ARRAY(req_streams_node)) { + uint64_t val; + int count = plist_array_get_size(req_streams_node); + for (int i = 0; i < count; i++) { + plist_t req_stream_node = plist_array_get_item(req_streams_node,0); + plist_t req_stream_type_node = plist_dict_get_item(req_stream_node, "type"); + plist_get_uint_val(req_stream_type_node, &val); + teardown_96 = (val == 96); + teardown_110 = (val == 110); + } + } + if (conn->raop->callbacks.teardown_request) { + conn->raop->callbacks.teardown_request(conn->raop->callbacks.cls, &teardown_96, &teardown_110); + } + logger_log(conn->raop->logger, LOGGER_DEBUG, "TEARDOWN request, 96=%d, 110=%d", teardown_96, teardown_110); + //http_response_add_header(*response, "Connection", "close"); + if (conn->raop_rtp != NULL && raop_rtp_is_running(conn->raop_rtp)) { - /* Destroy our RTP session */ raop_rtp_stop(conn->raop_rtp); } else if (conn->raop_rtp_mirror) { - /* Destroy our sessions */ + /* Destroy our sessions */ raop_rtp_destroy(conn->raop_rtp); conn->raop_rtp = NULL; raop_rtp_mirror_destroy(conn->raop_rtp_mirror); conn->raop_rtp_mirror = NULL; } - } - if (handler != NULL) { + } if (handler != NULL) { handler(conn, request, *response, &response_data, &response_datalen); } http_response_finish(*response, response_data, response_datalen); diff --git a/lib/raop.h b/lib/raop.h index 8b8a957..37a8d6a 100755 --- a/lib/raop.h +++ b/lib/raop.h @@ -41,6 +41,7 @@ struct raop_callbacks_s { /* Optional but recommended callback functions */ void (*conn_init)(void *cls); void (*conn_destroy)(void *cls); + void (*teardown_request)(void *cls, bool *teardown_96, bool *teardown_110 ); void (*audio_flush)(void *cls); void (*video_flush)(void *cls); void (*audio_set_volume)(void *cls, float volume); diff --git a/renderers/audio_renderer_gstreamer.c b/renderers/audio_renderer_gstreamer.c index 56f42ab..2e69f8a 100644 --- a/renderers/audio_renderer_gstreamer.c +++ b/renderers/audio_renderer_gstreamer.c @@ -157,7 +157,7 @@ void audio_renderer_start(unsigned char *ct) { if(compression_type != renderer->ct) { gst_app_src_end_of_stream(GST_APP_SRC(renderer->appsrc)); gst_element_set_state (renderer->pipeline, GST_STATE_NULL); - g_message ("changed audio connection, format %s\n", format[id]); + g_message ("changed audio connection, format %s", format[id]); renderer = renderer_type[id]; gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); } @@ -166,7 +166,7 @@ void audio_renderer_start(unsigned char *ct) { renderer = renderer_type[id]; gst_element_set_state (renderer->pipeline, GST_STATE_PLAYING); } else { - g_error( "unknown audio compression type ct = %d\n", *ct); + g_error("unknown audio compression type ct = %d", *ct); } } diff --git a/uxplay.cpp b/uxplay.cpp index cbf8fc1..c1b293e 100755 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -506,12 +506,16 @@ extern "C" void audio_set_volume (void *cls, float volume) { } extern "C" void audio_get_format (void *cls, unsigned char *ct, unsigned short *spf, bool *usingScreen, bool *isMedia, uint64_t *audioFormat) { - LOGI("ct=%d spf=%d usingScreen=%d isMedia=%d audioFormat=0x%lx",*ct, *spf, *usingScreen, *isMedia, (unsigned long) *audioFormat); + LOGI("ct=%d spf=%d usingScreen=%d isMedia=%d audioFormat=0x%lx",*ct, *spf, *usingScreen, *isMedia, (unsigned long) *audioFormat); if (use_audio) { audio_renderer_start(ct); } } +extern "C" void teardown(void *cls, bool *teardown_96, bool *teardown_110) { + LOGI("received TEARDOWN request from client, 96=%d 110 =%d", *teardown_96, *teardown_110); +} + extern "C" void log_callback (void *cls, int level, const char *msg) { switch (level) { case LOGGER_DEBUG: {