Support Windows in UPNP discovery (#8936)

* Support WIndows and Linix

* Correct indentation

* reduce line length

* Lint
This commit is contained in:
Steve 2017-08-19 23:26:27 +10:00 committed by Fabian Affolter
parent 84025e46ff
commit 5d52993231

View File

@ -2,7 +2,6 @@
import threading import threading
import socket import socket
import logging import logging
import os
import select import select
from aiohttp import web from aiohttp import web
@ -86,18 +85,6 @@ USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1
advertise_ip, advertise_port).replace("\n", "\r\n") \ advertise_ip, advertise_port).replace("\n", "\r\n") \
.encode('utf-8') .encode('utf-8')
# Set up a pipe for signaling to the receiver that it's time to
# shutdown. Essentially, we place the SSDP socket into nonblocking
# mode and use select() to wait for data to arrive on either the SSDP
# socket or the pipe. If data arrives on either one, select() returns
# and tells us which filenos have data ready to read.
#
# When we want to stop the responder, we write data to the pipe, which
# causes the select() to return and indicate that said pipe has data
# ready to be read, which indicates to us that the responder needs to
# be shutdown.
self._interrupted_read_pipe, self._interrupted_write_pipe = os.pipe()
def run(self): def run(self):
"""Run the server.""" """Run the server."""
# Listen for UDP port 1900 packets sent to SSDP multicast address # Listen for UDP port 1900 packets sent to SSDP multicast address
@ -119,7 +106,7 @@ USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1
socket.inet_aton(self.host_ip_addr)) socket.inet_aton(self.host_ip_addr))
if self.upnp_bind_multicast: if self.upnp_bind_multicast:
ssdp_socket.bind(("239.255.255.250", 1900)) ssdp_socket.bind(("", 1900))
else: else:
ssdp_socket.bind((self.host_ip_addr, 1900)) ssdp_socket.bind((self.host_ip_addr, 1900))
@ -130,16 +117,13 @@ USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1
try: try:
read, _, _ = select.select( read, _, _ = select.select(
[self._interrupted_read_pipe, ssdp_socket], [], [ssdp_socket], [],
[ssdp_socket]) [ssdp_socket], 2)
if self._interrupted_read_pipe in read: if ssdp_socket in read:
# Implies self._interrupted is True
clean_socket_close(ssdp_socket)
return
elif ssdp_socket in read:
data, addr = ssdp_socket.recvfrom(1024) data, addr = ssdp_socket.recvfrom(1024)
else: else:
# most likely the timeout, so check for interupt
continue continue
except socket.error as ex: except socket.error as ex:
if self._interrupted: if self._interrupted:
@ -148,6 +132,9 @@ USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1
_LOGGER.error("UPNP Responder socket exception occured: %s", _LOGGER.error("UPNP Responder socket exception occured: %s",
ex.__str__) ex.__str__)
# without the following continue, a second exception occurs
# because the data object has not been initialized
continue
if "M-SEARCH" in data.decode('utf-8'): if "M-SEARCH" in data.decode('utf-8'):
# SSDP M-SEARCH method received, respond to it with our info # SSDP M-SEARCH method received, respond to it with our info
@ -161,7 +148,6 @@ USN: uuid:Socket-1_0-221438K0100073::urn:schemas-upnp-org:device:basic:1
"""Stop the server.""" """Stop the server."""
# Request for server # Request for server
self._interrupted = True self._interrupted = True
os.write(self._interrupted_write_pipe, bytes([0]))
self.join() self.join()