From 3a3e72dfed76d19a378f4d4f0f9466f8768056f8 Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Sat, 3 Mar 2018 22:58:31 +0100 Subject: [PATCH 1/7] added logging to ddp messages --- pyps4/ddp.py | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/pyps4/ddp.py b/pyps4/ddp.py index bedcdc3..2247b38 100644 --- a/pyps4/ddp.py +++ b/pyps4/ddp.py @@ -3,13 +3,15 @@ import re import socket +import logging -UDP_IP = '0.0.0.0' +UDP_IP = '' UDP_PORT = 0 DDP_PORT = 987 DDP_VERSION = '00020020' +_LOGGER = logging.getLogger(__name__) def get_ddp_message(msg_type, data=None): """Get DDP message.""" @@ -66,18 +68,36 @@ def get_ddp_launch_message(credential): def _send_recv_msg(host, broadcast, msg, receive=True): """Send a ddp message and receive the response.""" - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.bind((UDP_IP, UDP_PORT)) - sock.settimeout(3.0) - if broadcast: - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - host = '255.255.255.255' - - sock.sendto(msg.encode('utf-8'), (host, DDP_PORT)) - - if receive: - return sock.recvfrom(1024) + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + except OSError as error: + _LOGGER.error('failed to create socket, %s', error) + return + try: + sock.bind((UDP_IP, UDP_PORT)) + sock.settimeout(3.0) + except OSError as error: + _LOGGER.error('failed to bind socket %s:%s, %s', UDP_IP, UDP_PORT, error) + sock.close() + return + + try: + if broadcast: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + host = '255.255.255.255' + + _LOGGER.debug('send_recv_msg %s [%s]', host, msg) + sock.sendto(msg.encode('utf-8'), (host, DDP_PORT)) + + if receive: + return sock.recvfrom(1024) + + sock.close() + except OSError as error: + _LOGGER.error('failed to send data using socket, %s', error) + sock.close() + return def _send_msg(host, broadcast, msg): From 01e804d19b0d5c580b7093342d98a842d70734dd Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Sat, 10 Mar 2018 10:47:23 +0100 Subject: [PATCH 2/7] trying to fix dependencies --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e370108..6fbc924 100755 --- a/setup.py +++ b/setup.py @@ -47,12 +47,12 @@ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Topic :: Software Development :: Libraries :: Python Modules', ], keywords = 'playstation sony ps4', install_requires = [ 'construct', - 'pycryptodome', 'pycryptodomex', ], entry_points = { From 4cdfad13b2ce8eadd85189ba00b96f58cb397963 Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Mon, 12 Mar 2018 13:16:37 +0100 Subject: [PATCH 3/7] handle errors in broadcast better --- pyps4/ddp.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/pyps4/ddp.py b/pyps4/ddp.py index 2247b38..1cc3c93 100644 --- a/pyps4/ddp.py +++ b/pyps4/ddp.py @@ -73,14 +73,14 @@ def _send_recv_msg(host, broadcast, msg, receive=True): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) except OSError as error: _LOGGER.error('failed to create socket, %s', error) - return + return [ None, host ] try: sock.bind((UDP_IP, UDP_PORT)) sock.settimeout(3.0) except OSError as error: _LOGGER.error('failed to bind socket %s:%s, %s', UDP_IP, UDP_PORT, error) sock.close() - return + return [ None, host ] try: if broadcast: @@ -97,7 +97,7 @@ def _send_recv_msg(host, broadcast, msg, receive=True): except OSError as error: _LOGGER.error('failed to send data using socket, %s', error) sock.close() - return + return [ None, host ] def _send_msg(host, broadcast, msg): @@ -107,15 +107,16 @@ def _send_msg(host, broadcast, msg): def search(host=None, broadcast=True): """Discover PS4s.""" + ps_list = [] msg = get_ddp_search_message() - data, addr = _send_recv_msg(host, broadcast, msg) - ps_list = [] - data = parse_ddp_response(data.decode('utf-8')) - data[u'host-ip'] = addr[0] - ps_list.append(data) + data, addr = _send_recv_msg(host, broadcast, msg) + if data is not None: + data = parse_ddp_response(data.decode('utf-8')) + data[u'host-ip'] = addr[0] + ps_list.append(data) return ps_list - + def get_status(host): """Get status.""" From c961db25836a1a5e8f1242a90d908d7d13d2625e Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Tue, 13 Mar 2018 09:13:23 +0100 Subject: [PATCH 4/7] added docker testing/dev env --- Dockerfile | 17 +++++++++++++++++ docker_run.sh | 14 ++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Dockerfile create mode 100755 docker_run.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b29da79 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.6 +MAINTAINER Henrik Nicolaisen + +ENV PATH "$PATH:/usr/local/bin" + +RUN apt-get update +RUN apt-get install -y tcpdump net-tools + +COPY . ps4 + +RUN cd ps4 && \ + python3 setup.py install --force + +ENTRYPOINT [ "ps4-ctrl" ] +CMD [ "-h", "-v" ] + +SHELL ["/bin/bash", "-c"] diff --git a/docker_run.sh b/docker_run.sh new file mode 100755 index 0000000..6864a90 --- /dev/null +++ b/docker_run.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Run in docker + +# Stop on errors +set -e + +docker build -t ps4-ctrl . +docker run --rm --net=host -it ps4-ctrl + +echo "-------------------" +echo "to test stuff use :" +echo " docker run --rm --net=host -it ps4-ctrl -v -C 903a0d528cd5029272d15d0d771d7bb0f4e09974779a21c351b0f6c321fca498 search" +echo " docker run --rm --net=host -it ps4-ctrl -v -H 10.254.2.107 -C 903a0d528cd5029272d15d0d771d7bb0f4e09974779a21c351b0f6c321fca498 wakeup" +echo " docker run --rm --net=host -it --entrypoint /bin/bash ps4-ctrl" From 5d02bd403a4483b2d32acd9c7863cca0c4cf01c6 Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Thu, 15 Mar 2018 08:06:51 +0100 Subject: [PATCH 5/7] return first item only --- pyps4/ddp.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyps4/ddp.py b/pyps4/ddp.py index 1cc3c93..047742c 100644 --- a/pyps4/ddp.py +++ b/pyps4/ddp.py @@ -116,12 +116,12 @@ def search(host=None, broadcast=True): data[u'host-ip'] = addr[0] ps_list.append(data) return ps_list - + def get_status(host): """Get status.""" - ps_list = search(host=host) - return ps_list[0] + for ps_list in search(host=host): + return ps_list def wakeup(host, credential, broadcast=None): From d7a7f46c5df1a6704636d1d6a43b7c714a04cdea Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Thu, 15 Mar 2018 08:23:44 +0100 Subject: [PATCH 6/7] handle missing data from search --- pyps4/ddp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyps4/ddp.py b/pyps4/ddp.py index 047742c..48d848f 100644 --- a/pyps4/ddp.py +++ b/pyps4/ddp.py @@ -122,6 +122,7 @@ def get_status(host): """Get status.""" for ps_list in search(host=host): return ps_list + return [] def wakeup(host, credential, broadcast=None): From d80877871a8e96323423d8cd7aade4c3c33ce3ec Mon Sep 17 00:00:00 2001 From: Henrik Nicolaisen Date: Thu, 15 Mar 2018 08:29:14 +0100 Subject: [PATCH 7/7] use dict instead of list --- pyps4/ddp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyps4/ddp.py b/pyps4/ddp.py index 48d848f..f5efe5e 100644 --- a/pyps4/ddp.py +++ b/pyps4/ddp.py @@ -122,7 +122,7 @@ def get_status(host): """Get status.""" for ps_list in search(host=host): return ps_list - return [] + return {} def wakeup(host, credential, broadcast=None):