Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device discovery and Roku TV #139

Open
iBicha opened this issue Jan 30, 2024 · 4 comments
Open

Device discovery and Roku TV #139

iBicha opened this issue Jan 30, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@iBicha
Copy link

iBicha commented Jan 30, 2024

I found myself fiddling with DIAL and lounge API, so I thought I'd share a couple of findings

So we get the response from SSDP discovery:

Cache-Control: max-age=3600
ST: urn:dial-multiscreen-org:service:dial:1
USN: ID::urn:dial-multiscreen-org:service:dial:1
Ext: 
Server: Roku/12.5.5 UPnP/1.0 Roku/12.5.5
LOCATION: http://IP:8060/dial/dd.xml
WAKEUP: MAC=MAC;Timeout=10

Right, so hitting the location (http://IP:8060/dial/dd.xml), and we need to read the response header Application-URL. Interestingly, the value for me is

Application-URL: http://IP:8060/dial

As you can see, there's no trailing slash, which might be causing an issue here
I guess the issue here is that we need to check for a trailing slash, and if it's not there, add it.

Next, when hitting http://IP:8060/dial/YouTube, it gets blocked (403) if you do not add this exact origin header

Origin: https://www.youtube.com

The response headers contain

Access-Control-Allow-Origin: https://www.youtube.com

So I guess that's something that needs to be added to the request here.

Finally, here's the content of http://IP:8060/dial/YouTube

<?xml version="1.0" encoding="UTF-8" ?>
<service
	xmlns="urn:dial-multiscreen-org:schemas:dial" dialVer="2.1">
	<name>YouTube</name>
	<options allowStop="true" />
	<state>running</state>
	<link rel="run" href="run" />
	<additionalData>
		<testYWRkaXR>c0ef1ca</testYWRkaXR>
		<brand>TCL</brand>
		<model>7130X</model>
		<yumi>XXXX</yumi>
		<passiveSessionId>XXXX</passiveSessionId>
	</additionalData>
</service>

So this is strange, since there's no screen id and no lounge id here. So this could cause an error.

Anyway, these are some observations, perhaps they are reasons why the discovery is not working for some people.

@iBicha iBicha added the bug Something isn't working label Jan 30, 2024
@iBicha
Copy link
Author

iBicha commented Jan 30, 2024

Based on this comment andrewsayre/pysmartthings#63 (comment), there's no screen Id or lounge or anything.
My (wild) guess is that Youtube took all this info to their backend, and you need to hit some API with the passiveSessionId somehow.

@iBicha iBicha changed the title Auto detection and Roku TV Device discovery and Roku TV Jan 30, 2024
@dmunozv04
Copy link
Owner

That’s very interesting, that would explain why auto discovery magically didn’t work for me when I tried to use it a couple weeks ago. Thanks for making such a detailed issue

@dmunozv04
Copy link
Owner

I've been trying to figure out how the passiveSessionId might work but the devices I have to test all still show the regular screenId parameter. I'd appreciate a mitm capture of a phone connecting to a device that has the passiveSessionId in order to keep investigating. I'll make the trailing slash fixed in the near future. Thanks for your insight

@iBicha
Copy link
Author

iBicha commented Feb 6, 2024

I didn't have time to do a capture, but I tried to understand the lounge/dial better. It turns out it is normal for the DIAL info of the app to not contain additionalData at all.

I think in some way, if the TV is already in a lounge, it might return additionalData (like screenId, loungeToken, etc) and this would allow the client (e.g. a phone) to immediately join a lounge. When additionalData is not present, in this case the phone sends a pairingCode to the TV, and the TV registers it using https://www.youtube.com/api/lounge/pairing/register_pairing_code. I still don't know how a phone generates the pairingCode (exactly which endpoint it hits)

My understanding is the lack of additionalData (or simply the lack of a lounge, device id, etc) is because there's no need to create, join and listen to changes in a lounge (which requires long polling) if there are no other devices expect the TV itself. So technically the TV can differ joining a lounge until another device joins.

https://github.com/patrickkfkan/yt-cast-receiver is a good resource to test against actually, and I understood some of the ins and outs better because of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants