kdschlosser / samsungctl

Remote control Samsung televisions via a TCP/IP connection
MIT License
148 stars 34 forks source link

What happens with an incorrect token #134

Open MikeFleetwood opened 4 years ago

MikeFleetwood commented 4 years ago

Hi - not really an "issue" just something I noticed that might be useful. I've not seen it mentioned elsewhere, but apologies if already dealt with!

If you attempt a WSS connection with an incorrect token, the TV still enables you to "allow" the connection. In this case, you will receive the normal "ms.channel.connect" message, however, the first "token":"xxxxx" that you find in the JSON string you receive is the incorrect token that you entered - so there's no point saving it for use next time. The JSON string will also include a second "token":"xxxxx", this time containing the correct token that you should have used - and should save for future use.

I found this by incorrectly storing the received token, so an incorrect value was used next time!

I hope this is useful!

Regards, Mike.

kdschlosser commented 4 years ago

This has not come up and is actually great information. If you could log the data received over the websocket connection when this takes place and paste it into a comment I can make the modifications needed to handle this.

MikeFleetwood commented 4 years ago

No problem - I'll send something in the next day or two. By the way, have you done any research on how long a token "lives"?

kdschlosser commented 4 years ago

I have not. I have an old TV so I am not able to test the websocket ones.

MikeFleetwood commented 4 years ago

I hope this helps:

GET /api/v2/channels/samsung.remote.control?name=QXVkaW9Cb3g=&token=90287863 HTTP/1.1 Host: 192.168.1.251:8002 Origin: 192.168.1.251:8002 Connection: Upgrade Upgrade: websocket Sec-WebSocket-Version: 13 Sec-WebSocket-Key: GAHMWJbs0ZkdtmibbEz/yA==

mbedtls_ssl_write, 257 bytes to send ...

Received from TV: {"data":{"clients":[{"attributes":{"name":"QXVkaW9Cb3g=","token":"90287863\n"},"connectTime":1589723841751,"deviceName":"QXVkaW9Cb3g=","id":"acd52a43-6d41-4479-8afb-852d25dbf514","isHost":false}],"id":"acd52a43-6d41-4479-8afb-852d25dbf514","token":"16673296"},"event":"ms.channel.connect"} Connected to TV Received token: 16673296

WebSocket sending 136 bytes Send to TV:{"method":"ms.remote.control","params":{"Cmd":"Click","DataOfCmd":"KEY_VOLDOWN","Option":false,"TypeOfRemote":"SendRemoteKey",}} - Sent OK Received WS control - ping Received WS control - ping Received WS control - connection close Closing

connection

The first section (before the "...") is the "GET" request sent to establish the WebSocket connection (I've not included the rest of the handshake) - note the spurious "newline" between the token and the "HTTP/1.1". Next is the "connect" message from the TV. Note the first "token" entry includes the extra "newline", so doesn't match the token the TV was expecting. The second token entry (16673296) is now the new valid token to use. I hope to fix the "newline" error today! Notice also, at the end of the sequence, two "ping" messages followed by a "close", after which we close the connection. The 3 messages received are at roughly 6 seconds intervals, and if we reply to "ping" with "pong", we can keep the connection open as long as we want. I don't know if the Python WebSocket functions give access to control messages - mine does, as I wrote it myself (smug smile). I wonder if you could do me an additional favour - please could you look at the 136 byte command message that I send after connection, and confirm there's no obvious errors? By the way, all these messages are sent/received via a TLSv1.2 connection (using mbedTLS).

kdschlosser commented 4 years ago

Your Option parameter is wrong. It needs to be "false" with the quotes.

The websocket connection in the library handles the pong internally. So the connection should stay open and active. The problem I was having with this library is detecting when the power on the TV is on or off. There are also some other bugs in the library that have to be worked through.

The token issue seems fairly simple I need to make it so that it will always get the new token I did not know that it would issue a new token if an invalid one was used.

I would be interested in checking out your websocket client. have you set up a build system for mbedTLS that is cross platform? How are you accessing mbedTLS? did you write a python c extension or are you using ctypes?

MikeFleetwood commented 4 years ago

Thanks for clearing up the Option parameter - I wasn't sure if the quotes were needed or not.

I can't help you with detecting the TV power state - I do all that thought CEC, including switching it on/off(standby) as needed.

Glad to be able to help with the token issue.

The websocket client was built from the "ground up", with reference to RFC documentation. I'd already made a websocket server, so for the client I basically reversed everything. For this work, I modified the client functions so that if the URL started with "WSS" instead of "WS" then the TLS interface was used instead of the LwIP send/receive that I use elsewhere. I imported all the mbedTLS source files into my IDE (Atollic for ARM embedded) alongside the rest of my source, made appropriate changes to their "config.h" file (took a while to get that right!) and customised the provided "net_sockets.c" file. I followed one of their example client files to get everything working. I don't use any Python code or translation in my project.

If it's any use to you, I'm happy to provide snippets of my code.

kdschlosser commented 4 years ago

OK so you are converting my library to C code. or grabbing the bits that you need from it anywho.

MikeFleetwood commented 4 years ago

Not quite. I started off with converting the "PySmartCrypto" interface for H/J model TVs into C. Unfortunately, I can't remember who was the original writer. I found that a C version had also been created by "Sectroyer", but I'd almost finished my own by then!

When we ugraded the TV our product gets installed with to the model M, I had to start again. This time I didn't try to re-write someone else's code (yours), but I did look for hints as to the URL to use to talk to the TV and the command protocol. And, yes, I have looked everywhere (on GitHub, at least) for applicable code to search for hints. Thank you, and others, for your research to unravel the protocols that Samsung won't publish! Anything I can do to contribute to that pool of Knowledge I am happy to do!

MikeFleetwood commented 4 years ago

Hi @kdschlosser I've just remembered another "cake crumb" that might be useful to you:

My apologies if you already know this, but hopefully it might be useful.

kdschlosser commented 4 years ago

I did not know about the 1:: or the 2:: thing and needing to be sent to the TV.

I did know about the Press and Release. I am using this when emulating the press of the press of the voice control button.

kdschlosser commented 4 years ago

I am going to put together a list of the commands I know about. and maybe you can add to that list.

There is also a debugging mode that can be enabled on the TV this is going to tell you what commands it has received and what has been sent as a response. This is use full if you connect the smart things application to the TV and use the features in it. You can then see what commands are available.

MikeFleetwood commented 4 years ago

I've done a bit of digging around the "hidden" menu. I spotted Debug - but couldn't figure out what you're supposed to do with it.

I think I only added two command to the various lists I've seen - KEY_EXIT (to exit from a menu, as opposed to going back a level) and KEY_APP_LIST (does what it says - although I can't remember if it actually works).