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

Get token UE40J5200AKXZT #21

Open
dariob84 opened this issue Apr 13, 2020 · 52 comments
Open

Get token UE40J5200AKXZT #21

dariob84 opened this issue Apr 13, 2020 · 52 comments

Comments

@dariob84
Copy link

Good morning,
i tried to take token for my tv (UE40J5200AKXZT) but i recived this:

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080
Traceback (most recent call last):
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 156, in _new_conn
conn = connection.create_connection(
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\connection.py", line 84, in create_connection
raise err
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\util\connection.py", line 74, in create_connection
sock.connect(sa)
ConnectionRefusedError: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
httplib_response = self._make_request(
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connectionpool.py", line 387, in _make_request
conn.request(method, url, **httplib_request_kw)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1230, in request
self._send_request(method, url, body, headers, encode_chunked)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1276, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1225, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 1004, in _send_output
self.send(msg)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\http\client.py", line 944, in send
self.connect()
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 184, in connect
conn = self._new_conn()
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\urllib3\connection.py", line 168, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x00000257CA59CD00>: Failed to establish a new connection: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

can anyone tell me what am i doing wrong?

Thanks

@sermayoral
Copy link
Owner

It seems IP not reached:

ConnectionRefusedError: [WinError 10061] Impossibile stabilire la connessione. Rifiuto persistente del computer di destinazione

Do you have the TV on? Are you sure the IP is right?

@dariob84
Copy link
Author

thanks for your reply
my tv is on and connected to the internet. the IP address is correct (I use a static IP address). I have two TVs of the same model and I get the same error.

@dariob84
Copy link
Author

dariob84 commented Apr 15, 2020 via email

@sermayoral
Copy link
Owner

@dariob84 I think your TV is blocking the request in some way.

If I remember well, there was an option in the TV menu to permit one IP to control the TV. You can try it

@md1980
Copy link

md1980 commented Aug 14, 2020

I have this problem:
image

@flostingapplesauce
Copy link

Has anyone successfully received a token on a J series? I have the program running under both under Windows 10 and Debian, but neither can get a token. Weirdly, the error always shows port 8000 is being tried.

The TV is a UN40J6203 (specifically a UN40J6200AFXZA) and it IS on the net. nMap shows port 8080 open.

Crypto.SelfTest passes fine.

Linux command:

python3 ./get_token.py -i 192.168.75.210 -p 8080

Linux log:

File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1604341144630 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb5f30a10>: Failed to establish a new connection: [Errno 111] Connection refused'))

Windows 10 command: get_token.py --ip 192.168.75.210 --port 8080

Windows 10 log:

raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1604341184884 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000288FC26EB20>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it'))

Both indicate port 8000 and both show the connection being refused.

I have tried all manner of syntax, -i IP -p PORT; --i IP --p PORT; -ip IP -port PORT; --ip IP --port PORT etcetc to no avail.

Is it that I am somehow still doing something wrong, or is the J6200 series not compatible?

@EPMatt
Copy link

EPMatt commented Nov 23, 2020

@flostingapplesauce the issue with the bad port should be fixed as of commit 2524a61.
You could try executing python get_token.py --ip <your ip> --port <your port> and see what results you get.

I'm having a similar issue with a J series Smart TV too (more details here #62).

@flostingapplesauce
Copy link

Thanks a million, EPMatt, but I am still getting a page of errors. Same errors when attempting it from the HA box and from a Windows machine. I can see the port is open with nmap, and can hit it with SSH, so I know the IP and port are correct. Although the error is identical when I use --port 8000 and nmap and ssh show 8000 is closed.

bash-5.0# python get_token.py --ip 192.168.75.210 --port 8080
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 169, in _new_conn
conn = connection.create_connection(
File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 96, in create_connection
raise err
File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 86, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 394, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 234, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "/usr/local/lib/python3.8/http/client.py", line 1255, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/lib/python3.8/http/client.py", line 1301, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.8/http/client.py", line 1250, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.8/http/client.py", line 1010, in _send_output
self.send(msg)
File "/usr/local/lib/python3.8/http/client.py", line 950, in send
self.connect()
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 200, in connect
conn = self._new_conn()
File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 181, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0xb509f040>: Failed to establish a new connection: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 439, in send
resp = conn.urlopen(
File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 755, in urlopen
retries = retries.increment(
File "/usr/local/lib/python3.8/site-packages/urllib3/util/retry.py", line 573, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1606409526220 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb509f040>: Failed to establish a new connection: [Errno 111] Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "get_token.py", line 27, in
main(sys.argv[1:])
File "get_token.py", line 24, in main
PySmartCrypto(ip, port)
File "/config/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 123, in init
self._connection = self.connect()
File "/config/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 95, in connect
websocket_response = requests.get(step4_url)
File "/usr/local/lib/python3.8/site-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/usr/local/lib/python3.8/site-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.75.210', port=8000): Max retries exceeded with url: /socket.io/1/?t=1606409526220 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb509f040>: Failed to establish a new connection: [Errno 111] Connection refused'))
bash-5.0# ssh -p 8080 192.168.75.210

@EPMatt
Copy link

EPMatt commented Nov 26, 2020

Hi @flostingapplesauce,
you're welcome! I'm happy to help as I can. :)

Did you clone this repo as of the latest commit?

I think this could be the problem since you're passing port 8080 as a parameter to the script, but you're still getting errors related to port 8000. This issue has been completely fixed with the latest merged PR.

Regarding the HA box, the issue is that there's no new version for this integration on HACS since the latest fix, so the code on your HA box could still be the buggy one from version v3.1.

I'd suggest trying the following:

  • clone this repository on your Windows machine (using git clone or downloading the zip here);
  • run python get_token.py --ip <your ip> --port <your port> from your Windows machine and see what results you get.

Please let us know if running the script as suggested allows you to get the token.
If you still get errors, you could paste the log here. 👍🏻

@flostingapplesauce
Copy link

Thanks again EPMatt, it is indeed different once I had the newest software. Now I get a 400 Bad Request, so at least it is seeing something.

Just in case it helps:

C:\Samsung>python get_token.py --ip 192.168.75.210 --port 8080
Traceback (most recent call last):
File "C:\Samsung\get_token.py", line 40, in
main(sys.argv[1:])
File "C:\Samsung\get_token.py", line 36, in main
PySmartCrypto(ip, port)
File "C:\Samsung\PySmartCrypto\pysmartcrypto.py", line 123, in init
self._connection = self.connect()
File "C:\Samsung\PySmartCrypto\pysmartcrypto.py", line 99, in connect
connection = websocket.create_connection(websocket_url)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 515, in create_connection
websock.connect(url, **options)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 226, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 80, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

@dariob84
Copy link
Author

dariob84 commented Nov 27, 2020

Hi EPMatt,
i tried to follow your instructions, but i can't get the token.

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080
Traceback (most recent call last):
File "get_token.py", line 40, in
main(sys.argv[1:])
File "get_token.py", line 36, in main
PySmartCrypto(ip, port)
File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 123, in init
self._connection = self.connect()
File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 99, in connect
connection = websocket.create_connection(websocket_url)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 515, in create_connection
websock.connect(url, **options)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 226, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 80, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

@EPMatt
Copy link

EPMatt commented Nov 29, 2020

Hi @flostingapplesauce @dariob84,
thank you for performing these tests, but here's where I got stuck. Unfortunately I think we have the same issue.

Just for testing purposes and be sure that our devices are behaving in the same way, try to add this after websocket_response = requests.get(step4_url) (line 95) in custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py:

print(websocket_response)

You'd probably see <Response [403]> in the output before the exception traceback.

Could you please check and confirm it?

@AKuHAK
Copy link

AKuHAK commented Nov 29, 2020

You'd probably see <Response [403]> in the output before the exception traceback.

Hi guys
I have UE32H4500
I also receive Response 403 after adding websocket_response = requests.get(step4_url)

But I can successfully connect with this code (I receive PIN and it responds correctly):
https://github.com/eclair4151/SmartCrypto/blob/master/PySmartCrypto/smartcrypto.py

@AKuHAK
Copy link

AKuHAK commented Nov 29, 2020

After reverting this commit: 2524a61
Everything is ok now:
We must use port 8000 for sending websocket, not the user defined port.

@EPMatt
Copy link

EPMatt commented Nov 30, 2020

Hi @AKuHAK ,

After reverting this commit: 2524a61
Everything is ok now:
We must use port 8000 for sending websocket, not the user defined port.

I'm happy to hear that you managed to get the token. 🚀
Unfortunately our TVs are quite different. Specifically, your device is a 2014 H-Series TV, which as I can read in other issues, exposes the web service on port 8000, while ours are all part of the 2015 J-Series. If we try to perform queries on port 8000, we just get a Connection refused exception.

Just for testing purposes, could you try retrieving the token with the code at the most recent commit?
Use python get_token.py --ip <your ip> --port 8000.

But I can successfully connect with this code (I receive PIN and it responds correctly):
https://github.com/eclair4151/SmartCrypto/blob/master/PySmartCrypto/smartcrypto.py

Thankyou very much for pointing it out!
@dariob84 @flostingapplesauce, it's a good idea to test other scripts and see if we can retrieve the token in some way. I'll definitely check it out and report any progress here. 👍🏻

@AKuHAK
Copy link

AKuHAK commented Nov 30, 2020

Here are my tests:
At latest commit:

  1. python get_token.py --ip <your ip> --port 8000
    After running with port 8000 I receive the correct console output:
<Response [200]>
Pin ON TV
Please enter pin from tv:

However, there is no PIN on the TV screen.
2) python get_token.py --ip <your ip> --port 8080
After running with port 8080 I receive Handshake error 400:

If I revert to 4eab94a:
3)

git checkout --force 4eab94a
python get_token.py --ip <your ip> --port 8080

I can see the PIN on the screen and PIN is correctly handled and I can successfully get token and session ID.

So I made an assumption that the PIN request port is hardcoded to 8000, maybe I am wrong. Of course, it will be better to run the same tests on some other TV (J series for example).

@dariob84
Copy link
Author

dariob84 commented Dec 1, 2020

@EPMatt

Hi,
I added the code this after line 95:

print(websocket_response)

this is the response

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080
Traceback (most recent call last):
File "get_token.py", line 40, in
main(sys.argv[1:])
File "get_token.py", line 36, in main
PySmartCrypto(ip, port)
File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 123, in init
self._connection = self.connect()
File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 99, in connect
connection = websocket.create_connection(websocket_url)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 515, in create_connection
websock.connect(url, **options)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 226, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 80, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

@flostingapplesauce
Copy link

flostingapplesauce commented Dec 1, 2020

EPMatt: I wasn't certain whether you wanted that line appended to the end of line 95, or added after it as line 96, so here it is both ways:

Appended:

C:\samsung> python get_token.py --ip 192.168.75.210 --port 8080
Traceback (most recent call last):
File "C:\samsung\get_token.py", line 4, in
from PySmartCrypto.pysmartcrypto import PySmartCrypto
File "C:\samsung\PySmartCrypto\pysmartcrypto.py", line 95
websocket_response = requests.get(step4_url) print(websocket_response)

Added as line 96:

C:\samsung> python get_token.py --ip 192.168.75.210 --port 8080 <Response [403]>
Traceback (most recent call last):
File "C:\samsung\get_token.py", line 40, in
main(sys.argv[1:])
File "C:\samsung\get_token.py", line 36, in main
PySmartCrypto(ip, port)
File "C:\samsung\PySmartCrypto\pysmartcrypto.py", line 124, in init
self._connection = self.connect()
File "C:\samsung\PySmartCrypto\pysmartcrypto.py", line 100, in connect
connection = websocket.create_connection(websocket_url)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 515, in create_connection
websock.connect(url, **options)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_core.py", line 226, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 80, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

Agreed, it looks like we have similar issues here. I am pretty sure that, at least on my end, I forgot to blow cigar smoke into the face of the sacrificial chicken last time I performed a ritual to the Python goddess, but it could be something else. ;)

@EPMatt
Copy link

EPMatt commented Dec 1, 2020

Hi @AKuHAK,
Thank you so much for performing these tests. 🚀
So I'm trying to make a recap and guess what had happened in your situation.

At latest commit:

  1. python get_token.py --ip <your ip> --port 8000
    After running with port 8000 I receive the correct console output:
<Response [200]>
Pin ON TV
Please enter pin from tv:

However, there is no PIN on the TV screen.

step4_url: using port 8000
websocket_url: using port 8000

  1. python get_token.py --ip <your ip> --port 8080
    After running with port 8080 I receive Handshake error 400:

step4_url: using port 8080
websocket_url: using port 8080

If I revert to 4eab94a:
3)

git checkout --force 4eab94a
python get_token.py --ip <your ip> --port 8080

I can see the PIN on the screen and PIN is correctly handled and I can successfully get token and session ID.

step4_url: using port 8000
websocket_url: using port 8000

This time the pin was displayed, and you were able to get the token. I saw similar issues, with people being able to display the pin after several attempts. So this second request on the same port probably triggered what the first one didn't.

We can then assume that H Series TVs (or at least yours) expose the service on port 8000. But it's interesting that you get a 400 when trying to connect on port 8080.

So I made an assumption that the PIN request port is hardcoded to 8000, maybe I am wrong. Of course, it will be better to run the same tests on some other TV (J series for example).

I performed the tests trying with port 8000 and also manually editing the code to make the first request to step4_url with port 8000 and the second one to websocket_url with port 8080.
What I get is a Connection refused message in both situations, stuck at performing the first request.

We can then assume that J Series TVs (or at least mine) don't expose the service on port 8000.

I'm only trying to guess, I think it's really difficult to debug these issues, since every device is a little different from the others, and this integration tries to manage all of them.

By the way might be interesting and extremely helpful to add to the docs, for each tested device, which port was used for connecting and retrieving the token. 👍🏻

@EPMatt
Copy link

EPMatt commented Dec 1, 2020

Hi @dariob84,
thank you very much for your feedback!

this is the response

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080
Traceback (most recent call last):
File "get_token.py", line 40, in
.....
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

That's strange, I don't see the output which should be generated by that new line. Maybe I was wrong with the line numbers in my previous comment, please make sure the connect function looks like this:

def connect(self):
      millis = int(round(time.time() * 1000))
      step4_url = 'http://' + self._host + ':'+self._port+'/socket.io/1/?t=' + str(millis)
      websocket_response = requests.get(step4_url)
      print(websocket_response)
      websocket_url = 'ws://' + self._host + ':'+self._port+'/socket.io/1/websocket/' + websocket_response.text.split(':')[0]
      # print(websocket_url)
      # pairs to this app with this command.
      connection = websocket.create_connection(websocket_url)
      connection.send('1::/com.samsung.companion')
      return connection

If you have time please retry, so that we're sure we're having all the same issue. 👍🏻

@EPMatt
Copy link

EPMatt commented Dec 1, 2020

Hi @flostingapplesauce,
thank you for your feedback! 🚀

Added as line 96:

C:\samsung> python get_token.py --ip 192.168.75.210 --port 8080 <Response [403]>
...
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

There you go! I think we're definitely on the same boat.

Agreed, it looks like we have similar issues here. I am pretty sure that, at least on my end, I forgot to blow cigar smoke into the face of the sacrificial chicken last time I performed a ritual to the Python goddess, but it could be something else. ;)

Hahah maybe you're right, neither did I! 😆
At least we're understanding that many people aren't able to get the token from their devices, and for the same reason.

@AKuHAK
Copy link

AKuHAK commented Dec 1, 2020

step4_url: using port 8000
websocket_url: using port 8000

Please recheck in step 3 I am using
step4_url: using port 8080
websocket_url: using port 8000

@EPMatt
Copy link

EPMatt commented Dec 1, 2020

Hi @AKuHAK,

Please recheck in step 3 I am using
step4_url: using port 8080
websocket_url: using port 8000

If I'm not wrong this should be the definition of the connect function at 4eab94a:

def connect(self):
        millis = int(round(time.time() * 1000))
        step4_url = 'http://' + self._host + ':8000/socket.io/1/?t=' + str(millis)
        websocket_response = requests.get(step4_url)
        websocket_url = 'ws://' + self._host + ':8000/socket.io/1/websocket/' + websocket_response.text.split(':')[0]
        # print(websocket_url)
        # pairs to this app with this command.
        connection = websocket.create_connection(websocket_url)
        connection.send('1::/com.samsung.companion')
        return connection

So the self._port is not taken into account when constructing the URLs. Hence:

step4_url: using port 8000
websocket_url: using port 8000

@AKuHAK
Copy link

AKuHAK commented Dec 1, 2020

Yes but I am running
python get_token.py --ip --port 8080
port 8080 is defined via command line so it should be used somewhere

if I run
python get_token.py --ip --port 8000
I got the same behavior in the latest commit and in the previous commit: the command line responds that PIN is ok, but does not show that PIN on the screen.

@EPMatt
Copy link

EPMatt commented Dec 1, 2020

Hi @AKuHAK,

Yes but I am running
python get_token.py --ip --port 8080
port 8080 is defined via command line so it should be used somewhere

You're right, I can see the port argument is used in getFullUrl.

That's interesting. For me running the commands as you described returns Connection refused.
Also, nmap detects only 8080 as open port, not 8000. So it looks like my device can't accept connections on 8000.

Just for testing purposes, could you please run nmap -PN <your_ip> to see which ports are open on your TV?

@AKuHAK
Copy link

AKuHAK commented Dec 1, 2020

Oh, I see, the port is used in 3 places, my mistake.
nmap -PN output

Not shown: 994 closed ports
PORT     STATE SERVICE
7676/tcp open  imqbrokerd
8000/tcp open  http-alt
8001/tcp open  vcom-tunnel
8080/tcp open  http-proxy
8443/tcp open  https-alt
9090/tcp open  zeus-admin

@flostingapplesauce
Copy link

Same. Port 8000 gives me [WinError 10061] No connection could be made because the target machine actively refused it')) and port 8080 returns a 400 error, both with and without that mod to the line after 95.

@EPMatt
Copy link

EPMatt commented Dec 1, 2020

Hi @AKuHAK,
it looks like your device has lots of opened ports.
Did you tweak any specific setting on your TV for enabling remote control?
Can you find any setting related to remote control in the configuration menus?

@flostingapplesauce
Copy link

FWIW, mine has:

7011
7676
8080

open.

@AKuHAK
Copy link

AKuHAK commented Dec 2, 2020

Hi @AKuHAK,
it looks like your device has lots of opened ports.
Did you tweak any specific setting on your TV for enabling remote control?
Can you find any setting related to remote control in the configuration menus?

Yes, I am logged in with a Samsung account and get Samsung smartthings token as described here:
https://github.com/balmli/com.samsung.smart#smartthings-api

@EPMatt
Copy link

EPMatt commented Dec 2, 2020

FWIW, mine has:

7011
7676
8080

open.

@flostingapplesauce thank you very much, we could check which services our devices expose on the network.

@flostingapplesauce @dariob84 could you please post the entire output of nmap <your_ip> just as @AKuHAK did?
So we can compare exposed services and opened ports.

For my device (UE32J5200):

PORT     STATE SERVICE
7676/tcp open  imqbrokerd
8080/tcp open  http-proxy

@estevez-dev
Copy link

I feel that I need to move my report here from #62 because we already have a lot of similar issues here.
So my TV is UE55H6203AK
Executing

python3 ./get_token.py --ip 192.168.2.23 --port 8080

Gives me this output (I've added print(websocket_response) to see a response):

<Response [403]>
Traceback (most recent call last):
  File "./get_token.py", line 40, in <module>
    main(sys.argv[1:])
  File "./get_token.py", line 36, in main
    PySmartCrypto(ip, port)
  File "/home/estevez/src/ha-samsungtv-encrypted/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 124, in __init__
    self._connection = self.connect()
  File "/home/estevez/src/ha-samsungtv-encrypted/custom_components/samsungtv_encrypted/PySmartCrypto/pysmartcrypto.py", line 100, in connect
    connection = websocket.create_connection(websocket_url)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_core.py", line 515, in create_connection
    websock.connect(url, **options)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_core.py", line 226, in connect
    self.handshake_response = handshake(self.sock, *addrs, **options)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_handshake.py", line 80, in handshake
    status, resp = _get_resp_headers(sock)
  File "/home/estevez/.local/lib/python3.7/site-packages/websocket/_handshake.py", line 165, in _get_resp_headers
    raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

I'm getting Connection refused when trying to use 8000 in any case.
I tried this:

python3 ./get_token.py --ip 192.168.2.23 --port 8000

I also tried to hardcode 8000 in connect function for step4_url, for websocket_url and for both. The answer is always the same:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.2.23', port=8000): Max retries exceeded with url: /socket.io/1/?t=1606845620690 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ae57b664748>: Failed to establish a new connection: [Errno 111] Connection refused'))

So looks like 8000 is not an option for my TV as well.
The list of opened ports (nmap -PN 192.168.2.23):

PORT     STATE SERVICE
4443/tcp open  pharos
7676/tcp open  imqbrokerd
8080/tcp open  http-proxy
8443/tcp open  https-alt

I don't have an option to use API token anywhere on TV, but I logged in with Samsung account. Also, I found "Remote control" under "Support" menu. It displays a PIN on the screen to pass it to Samsung Support to enable remote control for them. Not sure if this is the same functionality, but I tried to use that PIN with SmartCrypto by eclair4151 and no luck. Actually, that script always gives me the same output:

Current state: stopped
Pin NOT on TV
Please enter pin from tv: 

And no PIN on TV is displayed.

@EPMatt
Copy link

EPMatt commented Dec 2, 2020

Hi @estevez-dev,
Your device doesn't have port 8000 opened. Unfortunately, that's the same issue we're having here.
For now we've proof that only @AKuHAK managed to get that port opened on his TV.

I can confirm the same behaviour with the SmartCrypto by eclair4151 script.

@EPMatt
Copy link

EPMatt commented Dec 2, 2020

Yes, I am logged in with a Samsung account and get Samsung smartthings token as described here:
https://github.com/balmli/com.samsung.smart#smartthings-api

@AKuHAK how did you use that token?

@AKuHAK
Copy link

AKuHAK commented Dec 2, 2020

Yes, I am logged in with a Samsung account and get Samsung smartthings token as described here:
https://github.com/balmli/com.samsung.smart#smartthings-api

@AKuHAK how did you use that token?

I didn't get it to work, unfortunately.

@flostingapplesauce
Copy link

bash-5.0# nmap -p- 192.168.75.210
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-02 09:59 EST
Nmap scan report for 192.168.75.210
Host is up (0.018s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
7011/tcp open talon-disc
7676/tcp open imqbrokerd
8080/tcp open http-proxy
MAC Address: 38:01:95:01:xx:xx (Samsung Electronics)

Nmap done: 1 IP address (1 host up) scanned in 39.87 seconds
bash-5.0#

@dariob84
Copy link
Author

dariob84 commented Dec 2, 2020

C:\temp\samsungtv_encrypted>python get_token.py --ip 192.168.1.31 --port 8080
<Response [403]>
Traceback (most recent call last):
File "get_token.py", line 40, in
main(sys.argv[1:])
File "get_token.py", line 36, in main
PySmartCrypto(ip, port)
File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 124, in init
self._connection = self.connect()
File "C:\temp\samsungtv_encrypted\PySmartCrypto\pysmartcrypto.py", line 100, in connect
connection = websocket.create_connection(websocket_url)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 515, in create_connection
websock.connect(url, **options)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_core.py", line 226, in connect
self.handshake_response = handshake(self.sock, *addrs, **options)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 80, in handshake
status, resp = _get_resp_headers(sock)
File "C:\Users\dbarb\AppData\Local\Programs\Python\Python38\lib\site-packages\websocket_handshake.py", line 165, in _get_resp_headers
raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 400 Bad Request

i ran nmap

C:\temp\samsungtv_encrypted>nmap -PN 192.168.1.31
Not shown: 998 closed ports
PORT STATE SERVICE
7676/tcp open imqbrokerd
8080/tcp open http-proxy

@EPMatt
Copy link

EPMatt commented Dec 3, 2020

Hi everyone,
while doing a little research I came across this mobile app which allows to control Samsung Smart TVs with a phone or a smartwatch.
In their manual they provide a list of compatible devices, which clearly states:

Interestingly, it states that @AKuHAK's TV series, H4xxx should not be compatible, but he managed to succesfully retrieve the token, since it's device provides the service on port 8000, while ours don't.

As stated in the app manual, below the list of compatible devices:

It’s important to understand that not all models within a Series are supported, as indicated in the last column.
If your H or J-Series TV doesn’t show a PIN code when myTifi requests for it, your TV is not compatible.

For H and J-Series they provide additional info here:

When connecting to your H or J-Series, myTifi requests a PIN code.
...
If your TV doesn’t show a PIN code, your TV is probably not compatible. These are TVs like J5200, J5300, J5205, J6203, J620D, etc. See the list of compatible models.

These are mid-range Smart TVs which are build with less powerful hardware. Therefor it’s not capable anymore to run all software features. As a result the feature for remote network control is disabled by Samsung.
Please note that this is not a limitation of myTifi, but a limited feature set of your Samsung TV.

I think that we can assume that our TVs don't support the remote control feature. We could perform other attempts, trying somehow to open port 8000, but I really doubt this is possible.

The only way I can imagine this could work is by editing some settings in the service menu (dangerous, especially without proper documentation) or upgrading the firmware to a version for a supported model (really bad things could happen, and the device could be easily bricked this way).

So in the end, I don't think it's worth it. My suggestion is to add an entry in the documentation clearly stating that unfortunately our devices are not compatible. :(

@EPMatt
Copy link

EPMatt commented Dec 3, 2020

@AKuHAK after looking at eclair4151's SmartCrypto implementation I can notice that the code uses the hardcoded port 8000 for connecting to the TV. So it seems intentional, and also as you reported, that was the only way you managed to get the pin displayed on the device.
That was my mistake, I'm sorry. I'm submitting a PR for reverting the changes in 4eab94a.

Btw, did you manage to get the Home Assistant integration to work with your device, after you had retrieved the token?

@AKuHAK
Copy link

AKuHAK commented Dec 3, 2020

@AKuHAK after looking at eclair4151's SmartCrypto implementation I can notice that the code uses the hardcoded port 8000 for connecting to the TV. So it seems intentional, and also as you reported, that was the only way you managed to get the pin displayed on the device.
That was my mistake, I'm sorry. I'm submitting a PR for reverting the changes in 4eab94a.

Btw, did you manage to get the Home Assistant integration to work with your device, after you had retrieved the token?

Yes, integration runs just fine, volume control works, source switch works. The only thing that doesnt work is power button, but it is no necessary cause I have broadlink RM.

I also integrated curl command that launch YouTube application on my TV.

I will later post all modifications that I made with my TV. Maybe some of them will open desired port for you too. I dont think that my tv is so unique in that terms.

@EPMatt
Copy link

EPMatt commented Dec 3, 2020

Hi @AKuHAK,
amazing, that could be very helpful, yep maybe there's a way to make this work also on our TVs.
Thank you so much, we'll wait before closing this issue then. 👍🏻

@flostingapplesauce
Copy link

Thank you EPMatt for all of your work.

This is likely not related, but there is an interesting community who work to root some Samsung televisions. Because, of course there would be 😆

https://www.samygo.tv

@estevez-dev
Copy link

Hi @EPMatt . Thanks for your investigation.
I've manager to enter service menu and found "Smart control" option that was disabled. Just want to inform you that enabling it didn't help =)
I need new TV ))

@AKuHAK
Copy link

AKuHAK commented Dec 4, 2020

Hi @AKuHAK,
amazing, that could be very helpful, yep maybe there's a way to make this work also on our TVs.
Thank you so much, we'll wait before closing this issue then. 👍🏻

I probably found the solution: You need to disable the Watchdog in the Service menu. Details here:
https://wiki.samygo.tv/index.php?title=Main_Page#Safety_Measures_.28which_you_shouldn.27t_start_without.29
Just press Info-Menu-Mute-Power while TV is off, navigate using up, down and select: Control -> Sub Option -> Watchdog -> [ on | off ]. Set it to off (by pressing Left or right) and reboot TV. You can also set RS-232 Jack to debug but it didn't make any changes for me.
nmap output with watchdog on:

PORT     STATE SERVICE
7676/tcp open  imqbrokerd
9090/tcp open  zeus-admin

nmap output with watchdog off:

PORT     STATE SERVICE
7676/tcp open  imqbrokerd
8000/tcp open  http-alt
8001/tcp open  vcom-tunnel
8080/tcp open  http-proxy
8443/tcp open  https-alt
9090/tcp open  zeus-admin

@estevez-dev
Copy link

estevez-dev commented Dec 4, 2020

Hi @AKuHAK
I tried this as well. No luck for my TV =(
Setting RS232 to debug is needed to be able to resurrect your TV once you'll kill it with some wrong Service Menu settings ;-)

@AKuHAK
Copy link

AKuHAK commented Dec 4, 2020

Try to log in with developer account: Login: develop, password: any
For me, ports opened only after a minute or two after login

@AKuHAK
Copy link

AKuHAK commented Dec 4, 2020

if port 8001 is opened this command will launch YouTube on your TV:
curl -X POST http://192.168.1.109:8001/ws/apps/YouTube

@AKuHAK
Copy link

AKuHAK commented Dec 4, 2020

Hi @AKuHAK
I tried this as well. No luck for my TV =(
Setting RS232 to debug is needed to be able to resurrect your TV once you'll kill it with some wrong Service Menu settings ;-)

Ok here is my setup (at least what I can remember so far).

  • just to be sure that everything is the same I updated to the latest firmware (2900), nothing changed - everything is the same, all ports are still open
  • install 3rd party app using this guide: https://wiki.samygo.tv/index.php?title=Install_user_Apps_on_H-Series For tests I installed ForkPlayer (IP 85.17.30.89) and launched that app to be sure that everything is ok.
  • my TV is connected over wifi IPv4 address to the 2.4Ghz network
  • I set up SmartThings account as described here: https://github.com/jaruba/ha-samsungtv-tizen/blob/master/Smartthings.md , in fact - I cannot see my TV on the list, it seems that Samsung removed support for pre-2015 TVs
  • Then I logged in with my account used in the previous step
  • I tested Screen Mirroring from my Samsung phone. TV asks for granting permissions at that step.
  • I also set up SmartThings application on my Android phone and played one video on my TV screen using Smart View.
  • Tested Wi-Fi Direct function with my TV (can be found in Network menu). I can connect to TV, but I can't send media files.
  • I tested from my pc (where I run python scripts) Windows 10 built-in Function "Cast to Device" (is possible to get this function by pressing the right mouse button on video files). Then my PC IP address appeared in Network -> Multimedia devices.

@AKuHAK
Copy link

AKuHAK commented Jan 6, 2021

BTW I performed Smart Hub reset and now I can use both ports: 8080 and 8001 for pairing. Maybe this will help people that have port 8001 closed. But you still need port 8000 opened for WebSocket requests.

tcp/7676 UPNP
tcp/8000 Main webservice port
tcp/8080 Secure Pairing port

Small tip: I managed how to get never expired tokens. Just use any session-id greater than 1.

@epenet
Copy link

epenet commented May 5, 2022

Small tip: I managed how to get never expired tokens. Just use any session-id greater than 1.

@AKuHAK I am working on implementing the SamsungTV J/H model functionnality into Home Assistant core, and I have just now stumbled upon this thread. I am interested to understand what you mean about the session-id.
My understanding is that the session-id is given to you by the pairing process, so how do you force a session-id greater than 1?

@AKuHAK
Copy link

AKuHAK commented May 5, 2022

@epenet I don't quite remember, but probably I just did 2 pairings in a row.

I recommend for proper debugging install root on your testing device: H-J series
Some useful commands:

curl -X GET -i http://192.168.1.184:8001/ms/1.0/
will show some ports and info
curl -X GET -i http://192.168.1.184:8001/ws/apps/
will show device capabilities
curl -X GET -i http://192.168.1.184:8001/api/v2/
will show firmware version capabilities
curl -X GET -i http://192.168.1.184:8000
will return "Server is running..."
curl -X GET -i http://192.168.1.184:8000/socket.io/1
if return token, that means that pin is supported
curl -X GET -i http://192.168.1.184:8080/ws/pairing\?step\=$\{step\}\&app_id\=$\{this._config.appId\}\&device_id\=$\{this._config.deviceId\}
PIN code test
curl -X GET -i http://192.168.1.184:8080/ws/apps/YouTube
curl -X GET -i http://192.168.1.184:8001/ws/apps/YouTube
will show info about youtube application, commands the same but from different port
curl -X POST -i http://192.168.1.184:8001/ws/apps/YouTube
will open YouTube application
only works with 8001 port, with 8080 port need Content-Length
curl -X DELETE -i http://192.168.1.184:8001/ws/apps/YouTube/run
curl -X DELETE -i http://192.168.1.184:8080/ws/apps/YouTube/run
will close YouTube application, works with both ports
curl -X GET -i http://192.168.1.184:8080/ws/apps/YouTube/install
the command for opening smarthub page with installation, only 8080 port, and only whitelisted apps will work

curl -X POST -i http://192.168.1.184:8001/api/v2/applications/111299001912
will open YouTube application through more modern api and port 8001
curl -X PUT -i http://192.168.1.184:8001/api/v2/applications/111299001912
will show some wrong information about YouTube application

curl -X POST -i http://192.168.1.184:8001/ws/apps/CloudPINPage
another pin code, purpose unknown
curl -X DELETE -i http://192.168.1.184:8001/ws/apps/CloudPINPage/run 
close pin code

curl -X POST -i http://192.168.1.184:8001/ws/apps/WebBrowser
open web browser
curl -X POST -i http://192.168.1.184:8001/api/v2/applications/101400000099
curl -X POST -i http://192.168.1.184:8001/ws/apps/SSO
works (select user) SSO
curl -X POST -i http://192.168.1.184:8001/api/v2/applications/111199001564
curl -X POST -i http://192.168.1.184:8001/ws/apps/AdHub
works (AdHub)
curl -X POST -i http://192.168.1.184:8001/api/v2/applications/11101200001
curl -X POST -i http://192.168.1.184:8001/ws/apps/Netflix
works (Netflix)
curl -X POST -i http://192.168.1.184:8001/api/v2/applications/20142100003
curl -X POST -i http://192.168.1.184:8001/ws/apps/emanual
works
curl -X POST -i http://192.168.1.184:8001/api/v2/pincode
curl -X DELETE -i http://192.168.1.184:8001/api/v2/pincode
works pin is shown

curl -X POST -i http://192.168.1.184:8001/ms/1.0/device/info/update
reet network settings



Next just should be open in web browser
http://192.168.1.184:8001/captcha.png
http://192.168.1.184:8001/resources/webapplauncher/

@epenet
Copy link

epenet commented May 5, 2022

I don't actually have a H-J model to test with, so I am relying on other users to test it !

If what you say is correct, then maybe we need to adjust the config-flow in async_step_reauth_confirm_encrypted to ask the user "Session-id is 1, which is known to expire under certain circumstances. Would you like to run the pairing again?"

https://github.com/home-assistant/core/blob/248f01f41f58682abc75a26f8ae16bd1516fba97/homeassistant/components/samsungtv/config_flow.py#L580

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants