Skip to content

Instantly share code, notes, and snippets.

@wmcbrine
Created August 1, 2022 02:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmcbrine/e44f27e53642a24e7fefcfd076cdfbe4 to your computer and use it in GitHub Desktop.
Save wmcbrine/e44f27e53642a24e7fefcfd076cdfbe4 to your computer and use it in GitHub Desktop.
Find TiVos on the LAN
#!/usr/bin/env python
# The way this is supposed to work is, we broadcast an announcement to
# port 2190, and wait for responses in kind. But that takes forever. The
# TiVo Connect Discovery spec says that machines should speed up their
# broadcast rate when they see a new machine on the network; in
# practice, it appears that TiVo Desktop does so, but real TiVo boxes
# don't -- they broadcast at ~65-second intervals, and don't change.
#
# However, they do respond _immediately_ with an HTTP request for a list
# of services, when the TCD packet says they're available, and it's an
# identity the TiVo hasn't seen before. So, that's what I've done here:
# set up a fake HTTP server to catch the requests.
import random
import re
import select
import socket
ANNOUNCE = """tivoconnect=1
method=broadcast
platform=pc
identity=remote%(port)d
services=TiVoMediaServer:%(port)d/http
"""
tcd_id = re.compile('TiVo_TCD_ID: (.*)\r\n').search
tivos = {}
# Find and bind a free port for our fake server.
hsock = socket.socket()
while True:
port = random.randint(32768, 65535)
try:
hsock.bind(('', port))
break
except:
pass
hsock.listen(5)
# Broadcast an announcement.
usock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
usock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
usock.sendto(ANNOUNCE % locals(), ('255.255.255.255', 2190))
usock.close()
# Collect the queries made in response. These come quickly.
while True:
isock, junk1, junk2 = select.select([hsock], [], [], 0.1)
if not isock:
break
client, address = hsock.accept()
message = client.recv(1500)
client.close() # This is rather rude.
print message
tivos[tcd_id(message).groups()[0]] = address[0]
hsock.close()
for key in tivos:
print key, tivos[key]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment