From 4df5400cb1615b558f133d12d601bae2e4bb7a4a Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Wed, 26 Jul 2017 16:00:20 -0700 Subject: [PATCH] tivo: Fix Bonjour compatibility with Bolt Bolt (Series6) seems to have a bug where it only reacts to _tivo-videostream._tcp service types after a TiVo reboot, and ignores _tivo-vidoes._tcp. I have no idea what the difference is supposed to be because it's undocumented, but either type works on both Roamio (Series5) and Bolt, so hopefully it's safe for Series 3 and 4 also. --- avahi.c | 128 +++++++++++++++++++++++++++--------------------------- clients.c | 7 +++ 2 files changed, 72 insertions(+), 63 deletions(-) diff --git a/avahi.c b/avahi.c index e48f66b..750542a 100644 --- a/avahi.c +++ b/avahi.c @@ -49,69 +49,10 @@ static struct context { * Private functions *****************************************************************/ -static void publish_reply(AvahiEntryGroup *g, - AvahiEntryGroupState state, - void *userdata); - -static int -_add_svc(const char *cat, const char *srv, const char *id, const char *platform) -{ - char name[128+1]; - char path[64]; - int ret; - - snprintf(name, sizeof(name), "%s on %s", cat, friendly_name); - snprintf(path, sizeof(path), - "path=/TiVoConnect?Command=QueryContainer&Container=%s", id); - - DPRINTF(E_INFO, L_SSDP, "Registering '%s'\n", name); - ret = avahi_entry_group_add_service(ctx.group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, - 0, name, srv, NULL, NULL, runtime_vars.port, - "protocol=http", path, platform, NULL); - if (ret < 0) - DPRINTF(E_ERROR, L_SSDP, "Failed to add %s: %s\n", - srv, avahi_strerror(avahi_client_errno(ctx.client))); - return ret; -} - -/* Try to register the TiVo DNS SRV service type. */ -static void -register_stuff(void) -{ - assert(ctx.client); - - if (!ctx.group) - { - ctx.group = avahi_entry_group_new(ctx.client, publish_reply, NULL); - if (!ctx.group) - { - DPRINTF(E_ERROR, L_SSDP, "Failed to create entry group: %s\n", - avahi_strerror(avahi_client_errno(ctx.client))); - return; - } - } - - if (avahi_entry_group_is_empty(ctx.group)) - { - if (_add_svc("Music", "_tivo-music._tcp", "1", NULL) < 0) - return; - if (_add_svc("Photos", "_tivo-photos._tcp", "3", NULL) < 0) - return; - if (_add_svc("Videos", "_tivo-videos._tcp", "2", "platform=pc/readydlna") < 0) - return; - if (avahi_entry_group_commit(ctx.group) < 0) - { - DPRINTF(E_ERROR, L_SSDP, "Failed to commit entry group: %s\n", - avahi_strerror(avahi_client_errno(ctx.client))); - return; - } - } -} - /* Called when publishing of service data completes */ static void publish_reply(AvahiEntryGroup *g, - AvahiEntryGroupState state, - AVAHI_GCC_UNUSED void *userdata) + AvahiEntryGroupState state, + AVAHI_GCC_UNUSED void *userdata) { assert(ctx.group == NULL || g == ctx.group); @@ -138,9 +79,65 @@ static void publish_reply(AvahiEntryGroup *g, } } +static int +_add_svc(const char *cat, const char *srv, const char *id, const char *platform) +{ + char name[128+1]; + char path[64]; + int ret; + + snprintf(name, sizeof(name), "%s on %s", cat, friendly_name); + snprintf(path, sizeof(path), + "path=/TiVoConnect?Command=QueryContainer&Container=%s", id); + + DPRINTF(E_INFO, L_SSDP, "Registering '%s'\n", name); + ret = avahi_entry_group_add_service(ctx.group, AVAHI_IF_UNSPEC, AVAHI_PROTO_INET, + 0, name, srv, NULL, NULL, runtime_vars.port, + "protocol=http", path, platform, NULL); + if (ret < 0) + DPRINTF(E_ERROR, L_SSDP, "Failed to add %s: %s\n", + srv, avahi_strerror(avahi_client_errno(ctx.client))); + + return ret; +} + +/* Try to register the TiVo DNS SRV service type. */ +static void +register_stuff(void) +{ + assert(ctx.client); + + if (!ctx.group) + { + ctx.group = avahi_entry_group_new(ctx.client, publish_reply, NULL); + if (!ctx.group) + { + DPRINTF(E_ERROR, L_SSDP, "Failed to create entry group: %s\n", + avahi_strerror(avahi_client_errno(ctx.client))); + return; + } + } + + if (avahi_entry_group_is_empty(ctx.group)) + { + if (_add_svc("Music", "_tivo-music._tcp", "1", NULL) < 0) + return; + if (_add_svc("Photos", "_tivo-photos._tcp", "3", NULL) < 0) + return; + if (_add_svc("Videos", "_tivo-videostream._tcp", "2", "platform=pc/"SERVER_NAME) < 0) + return; + if (avahi_entry_group_commit(ctx.group) < 0) + { + DPRINTF(E_ERROR, L_SSDP, "Failed to commit entry group: %s\n", + avahi_strerror(avahi_client_errno(ctx.client))); + return; + } + } +} + static void client_callback(AvahiClient *client, - AvahiClientState state, - void *userdata) + AvahiClientState state, + void *userdata) { ctx.client = client; @@ -202,6 +199,11 @@ void tivo_bonjour_unregister(void) { DPRINTF(E_DEBUG, L_SSDP, "tivo_bonjour_unregister\n"); + if (ctx.group) + { + avahi_entry_group_reset(ctx.group); + avahi_entry_group_free(ctx.group); + } if (ctx.threaded_poll) avahi_threaded_poll_stop(ctx.threaded_poll); if (ctx.client) diff --git a/clients.c b/clients.c index e889e74..b920258 100644 --- a/clients.c +++ b/clients.c @@ -275,6 +275,13 @@ struct client_type_s client_types[] = EUserAgent }, + { 0, + 0, + "TiVo", + "TvHttpClient", + EUserAgent + }, + { EStandardDLNA150, FLAG_DLNA | FLAG_MIME_AVI_AVI, "Generic DLNA 1.5",