jcarbaugh / python-roku

Screw remotes. Control your Roku with Python.
https://pypi.python.org/pypi/roku
BSD 3-Clause "New" or "Revised" License
294 stars 95 forks source link

discovery.py doesn't discover Roku 4 #19

Closed ajarara closed 5 years ago

ajarara commented 7 years ago

But it does provoke a response from it:

tcpdump output during a Roku.discover() call:

tcpdump -ne -i any port 1900
21:32:43.638146 Out <ma:ca:dd:re:ss> ethertype IPv4 (0x0800), length 138: 192.168.1.2.34202 > 239.255.255.250.ssdp: UDP, length 94
21:32:46.063044  In <ma:ca:dd:re:ss> ethertype IPv4 (0x0800), length 259: 192.168.1.8.ssdp > 192.168.5.2.34202: UDP, length 215

192.168.1.8 is indeed a Roku, so it's not the cast, it's the response not being picked up by the socket.

For a workaround I just query arp tables for the IP using something like:

ip neigh | awk '/ro:ku:ma:ca:dr/ { print $1 }' | tr -d '()'

and pass it to the application. This issue seems like a recurring issue with Python and multicast requests, so this can (and probably should) be closed, unless someone knows what's going on. I just figured this might be a good place to put it for those who ran into the same problem.

gsparx commented 7 years ago

I'm seeing similar behavior I believe. I've tried several different python implementations, and a golang implementation (my server is written in golang) and my Roku4 does not show up in the device list at all. It's driving me nuts. The Roku remote app discovers my Roku just fine (and I'm assuming it would also be using SSDP for this?) and I am at a complete loss as to why I can't use fairly vanilla SSDP discovery code to discover the Roku.

20:26:08.592797 <routerma:ca:dd:re:ss> > <unknownma:ca:dd:re:ss>, ethertype IPv4 (0x0800), length 136: 192.168.1.9.62042 > 239.255.255.250.1900: UDP, length 94
20:26:09.505483 <rokuma:ca:dd:re:ss> > <routerma:ca:dd:re:ss>1, ethertype IPv4 (0x0800), length 257: 192.168.1.10.1900 > 192.168.1.9.62042: UDP, length 215

My TCPdump looks a bit different from yours though (I'm on osx)

192.168.1.10 is definitely my roku device's IP. Any thoughts?

nitrocode commented 6 years ago

Using python3. I'm having a similar issue where Roku.discovery() returns nothing. UPnP and SSDP work fine from the command line to discover my roku at 192.168.1.33. I followed the SSDP ncat example from the sdkdocs and then read the packet capture. Replace 192.168.1.45 with your own host to reproduce results.

Using ncat to send the ssdp request and tcpdump to read the response

$ tcpdump -i wlp4s0 -nnvXSs 0 '(dst 192.168.1.45 and port 1900) or dst 239.255.255.250'
tcpdump: listening on wlp4s0, link-type EN10MB (Ethernet), capture size 262144 bytes
20:15:16.597922 IP (tos 0x0, ttl 1, id 40340, offset 0, flags [DF], proto UDP (17), length 110)
    192.168.1.45.38753 > 239.255.255.250.1900: UDP, length 82
    0x0000:  4500 006e 9d94 4000 0111 2a1b c0a8 012d  E..n..@...*....-
    0x0010:  efff fffa 9761 076c 005a c075 4d2d 5345  .....a.l.Z.uM-SE
    0x0020:  4152 4348 202a 2048 5454 502f 312e 310a  ARCH.*.HTTP/1.1.
    0x0030:  486f 7374 3a20 3233 392e 3235 352e 3235  Host:.239.255.25
    0x0040:  352e 3235 303a 3139 3030 0a4d 616e 3a20  5.250:1900.Man:.
    0x0050:  2273 7364 703a 6469 7363 6f76 6572 220a  "ssdp:discover".
    0x0060:  5354 3a20 726f 6b75 3a65 6370 0a0a       ST:.roku:ecp..
20:15:17.280928 IP (tos 0x0, ttl 64, id 36502, offset 0, flags [DF], proto UDP (17), length 243)
    192.168.1.33.1900 > 192.168.1.45.38753: UDP, length 215
        ...
    0x0080:  5365 7276 6572 3a20 526f 6b75 2055 506e  Server:.Roku.UPn
    0x0090:  502f 312e 3020 526f 6b75 2f38 2e31 2e30  P/1.0.Roku/8.1.0
    0x00a0:  0d0a 4c4f 4341 5449 4f4e 3a20 6874 7470  ..LOCATION:.http
    0x00b0:  3a2f 2f31 3932 2e31 3638 2e31 2e33 333a  ://192.168.1.33:
    0x00c0:  3830 3630 2f0d 0a57 414b 4555 503a 204d  8060/..WAKEUP:.M
        ...

Using Roku.discover() I get the same result except the function returns before the packet is captured. It seems to be timing out. Roku.discover(timeout=10) waited until the packet was returned and still returned an empty list... It looks like it's still timing out for some reason.

I ran the original code in python2 and it also returned nothing. tcpdump is showing the correct results. It's a pain in the butt to debug these socket issues...

Edit: Mon July 16s github went down and lost my edit. My issue was that my linux distro was blocking port 1900 udp so I enabled it within iptables and it worked.

ajarara commented 6 years ago

I no longer have easy access to a Roku to confirm that that works for me. @gsparx maybe there's an analog for macOS?

iantrich commented 5 years ago

Closing as this looks to be a configuration issue. Let me know if issue persists. Thanks!

daranday commented 4 years ago

Running into this issue as well on MacOS Mojave. Roku.discover() works the first time but not subsequent times until kernel is restarted.