eslavnov / pylips

Control Philips TVs (2015+) and Ambilight (+ Hue) through their reverse-engineered API (+ MQTT support!)
MIT License
342 stars 60 forks source link

[BUG]/[FEAT] Reuse SSL session to fix unresponsive API #49

Closed lantheman89 closed 4 years ago

lantheman89 commented 4 years ago

40PFT6550/12 stops responding to commands from pylips after a certain point. If the MQTT_update setting is on, it stops fairly quickly and on its own with no input necessary, but if it's disabled, it stops after a number of commands has been sent out and successfully received. The TV starts listening to commands again after it has been put on standby then woken up again.

As the official remote app works fine with any number of commands sent out and any length of time, this seems to be an issue in how the two connect and interact. I initially suspected that there was a missing protocol feature, like a reauthentification, rehandshaking or re-something after a number of commands, but it looks like Home Assistant users are on to something:

https://community.home-assistant.io/t/philips-android-tv-component/17749/14

h0bb3 I got this working on my 55pus727212, i.e. got the pairing code and could then use the component in home assistant (change volume worked fine).

However, after maybe 5-10 volume adjustment tests, it suddenly stopped working and I have not been able to pair it any more (i.e. nothing happens when doing this). Tried restarting the TV etc, but nothing. Any ideas?

https://community.home-assistant.io/t/philips-android-tv-component/17749/15

martijnv I experienced the same problem, after a minute or 10 the component stopped working because the television stopped responding to the requests. I ran some tests and found that after exactly 100 requests the REST API stopped working. I dug a little deeper with Wireshark and discovered that the problem was caused by the SSL-handshake. At request 101 the client send its SSL “client hello”, but the server did not give a “server hello” back anymore. My guess is that the webserver in the television caches SSL connections in an array of max 100 items.

I’m creating a new version that reuses the SSL connection. The test version that I’m running now appears to be stable this way. I’ve also added channel information, a volume slider en rewind/pause/forward functions. It’s almost done and I will share it very soon.

Sure enough, the following lines of the Home Assistant Philips TV component code say the following:

https://github.com/nstrelow/ha_philips_android_tv/blob/e786331c349937618e12c8b371ebde4d80339fbb/custom_components/philips_android_tv/media_player.py#L299

The XTV app appears to have a bug that limits the nummber of SSL session to 100 The code below forces the control to keep re-using a single connection

After martijnv's post, the issue no longer seems to crop up in the HA component thread so it's safe to assume that the issue is fixed by the solution.

Is this feasible to implement in pylips for us stubborn MQTT and Node-RED users? Thanks in advance!

eslavnov commented 4 years ago

Hey @lantheman89, thanks for the info! Did not know about the 100 sessions (why wouldn't they close inactive sessions?!), but this actually explains a lot! I'll see what I can do about it!

lantheman89 commented 4 years ago

Well, we are talking about TVs where the remote control stops working all of a sudden and the TV decides it doesn't want to start every once in a while, so the SSL thing isn't that much more odd or frustrating than anything else Philips did. 😊

Good luck!

zierka commented 4 years ago

Sorry to comment to a closed thread (let me know if this isn't the right place for this).

First of all thank you for developing this great utility! I'm building an iOS remote control app for Philips tv-s, and I'm basing it on your implementation (I'm reimplementing it in flutter/dart).

I think I also have this issue where after some requests subsequent requests are not executed on the TV, though I'm not sure.

After some requests I get

TLSv1.2 [Failed: handshake_failure (40) - Unable to negotiate an acceptable set of security parameters, this probably means there are no cipher suites in common]

I wonder if this is the same warning you got? I tried to fix it by configuring the http client but I'm not sure if it's working/it's the right setting.

Thanks.

eslavnov commented 4 years ago

Hey @zierka, I don't remember the exact error (and it will probably depend on the client you are using), but it looks like the same issue indeed. What you can try to do is sending a bunch of requests with a let's say 1 second interval and see at which point you stop getting a response - if it's around 100, then it's probably the same issue. You have to reuse the same SSL session as opposed to opening a new for each request, but the implementation will depend on the client you are using.

zierka commented 4 years ago

It doesn't seem to be a ~100 request issue. I can repro it easily by quickly making a lot of requests (~2/second). After a short time (~1-2 minutes) the problem goes away and I can make requests again. Are you not having issues after making requests quickly after each other?