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.
This commit is contained in:
Justin Maggard 2017-07-26 16:00:20 -07:00
parent b0cd672abf
commit 4df5400cb1
2 changed files with 72 additions and 63 deletions

120
avahi.c
View File

@ -49,65 +49,6 @@ static struct context {
* Private functions * 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 */ /* Called when publishing of service data completes */
static void publish_reply(AvahiEntryGroup *g, static void publish_reply(AvahiEntryGroup *g,
AvahiEntryGroupState state, AvahiEntryGroupState state,
@ -138,6 +79,62 @@ 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, static void client_callback(AvahiClient *client,
AvahiClientState state, AvahiClientState state,
void *userdata) void *userdata)
@ -202,6 +199,11 @@ void tivo_bonjour_unregister(void)
{ {
DPRINTF(E_DEBUG, L_SSDP, "tivo_bonjour_unregister\n"); 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) if (ctx.threaded_poll)
avahi_threaded_poll_stop(ctx.threaded_poll); avahi_threaded_poll_stop(ctx.threaded_poll);
if (ctx.client) if (ctx.client)

View File

@ -275,6 +275,13 @@ struct client_type_s client_types[] =
EUserAgent EUserAgent
}, },
{ 0,
0,
"TiVo",
"TvHttpClient",
EUserAgent
},
{ EStandardDLNA150, { EStandardDLNA150,
FLAG_DLNA | FLAG_MIME_AVI_AVI, FLAG_DLNA | FLAG_MIME_AVI_AVI,
"Generic DLNA 1.5", "Generic DLNA 1.5",