fast discovery with multi_m_search
-remove m_search_args from Gateway
This commit is contained in:
parent
68d6b815a1
commit
d8f309f8fe
4 changed files with 30 additions and 22 deletions
|
@ -8,7 +8,7 @@ from aioupnp.util import get_dict_val_case_insensitive
|
|||
from aioupnp.constants import SPEC_VERSION, SERVICE
|
||||
from aioupnp.commands import SOAPCommands, SCPDRequestDebuggingInfo
|
||||
from aioupnp.device import Device, Service
|
||||
from aioupnp.protocols.ssdp import fuzzy_m_search, m_search
|
||||
from aioupnp.protocols.ssdp import fuzzy_m_search, m_search, multi_m_search
|
||||
from aioupnp.protocols.scpd import scpd_get
|
||||
from aioupnp.serialization.ssdp import SSDPDatagram
|
||||
from aioupnp.util import flatten_keys
|
||||
|
@ -69,12 +69,10 @@ def parse_location(location: bytes) -> typing.Tuple[bytes, int]:
|
|||
|
||||
|
||||
class Gateway:
|
||||
def __init__(self, ok_packet: SSDPDatagram, m_search_args: typing.Dict[str, typing.Union[int, str]],
|
||||
lan_address: str, gateway_address: str,
|
||||
def __init__(self, ok_packet: SSDPDatagram, lan_address: str, gateway_address: str,
|
||||
loop: typing.Optional[asyncio.AbstractEventLoop] = None) -> None:
|
||||
self._loop = loop or asyncio.get_event_loop()
|
||||
self._ok_packet = ok_packet
|
||||
self._m_search_args = m_search_args
|
||||
self._lan_address = lan_address
|
||||
self.usn: bytes = (ok_packet.usn or '').encode()
|
||||
self.ext: bytes = (ok_packet.ext or '').encode()
|
||||
|
@ -149,7 +147,6 @@ class Gateway:
|
|||
'gateway_xml': self._xml_response.decode(),
|
||||
'services_xml': self._service_descriptors,
|
||||
'services': {service.SCPDURL: service.as_dict() for service in self._services},
|
||||
'm_search_args': OrderedDict(self._m_search_args),
|
||||
'reply': self._ok_packet.as_dict(),
|
||||
'soap_port': self.port,
|
||||
'registered_soap_commands': self._registered_commands,
|
||||
|
@ -170,14 +167,13 @@ class Gateway:
|
|||
]
|
||||
while True:
|
||||
if not igd_args:
|
||||
m_search_args, datagram = await fuzzy_m_search(
|
||||
datagram = await multi_m_search(
|
||||
lan_address, gateway_address, timeout, loop, ignored, unicast
|
||||
)
|
||||
else:
|
||||
m_search_args = OrderedDict(igd_args)
|
||||
datagram = await m_search(lan_address, gateway_address, igd_args, timeout, loop, ignored, unicast)
|
||||
try:
|
||||
gateway = cls(datagram, m_search_args, lan_address, gateway_address, loop=loop)
|
||||
gateway = cls(datagram, lan_address, gateway_address, loop=loop)
|
||||
log.debug('get gateway descriptor %s', datagram.location)
|
||||
await gateway.discover_commands()
|
||||
requirements_met = all([gateway.commands.is_registered(required) for required in required_commands])
|
||||
|
|
|
@ -152,6 +152,21 @@ async def m_search(lan_address: str, gateway_address: str, datagram_args: Dict[s
|
|||
protocol.disconnect()
|
||||
|
||||
|
||||
async def multi_m_search(lan_address: str, gateway_address: str, timeout: int = 3,
|
||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
||||
ignored: Set[str] = None, unicast: bool = False) -> SSDPDatagram:
|
||||
protocol, gateway_address, lan_address = await listen_ssdp(
|
||||
lan_address, gateway_address, loop, ignored, unicast
|
||||
)
|
||||
datagram_args = list(packet_generator())
|
||||
try:
|
||||
return await protocol.m_search(address=gateway_address, timeout=timeout, datagrams=datagram_args)
|
||||
except asyncio.TimeoutError:
|
||||
raise UPnPError("M-SEARCH for {}:{} timed out".format(gateway_address, SSDP_PORT))
|
||||
finally:
|
||||
protocol.disconnect()
|
||||
|
||||
|
||||
async def _fuzzy_m_search(lan_address: str, gateway_address: str, timeout: int = 30,
|
||||
loop: Optional[asyncio.AbstractEventLoop] = None,
|
||||
ignored: Set[str] = None,
|
||||
|
|
|
@ -176,8 +176,7 @@ class TestDiscoverDLinkDIR890L(AsyncioTestCase):
|
|||
[('serviceType', 'urn:schemas-upnp-org:service:WANIPConnection:1'),
|
||||
('serviceId', 'urn:upnp-org:serviceId:WANIPConn1'), ('controlURL', '/soap.cgi?service=WANIPConn1'),
|
||||
('eventSubURL', '/gena.cgi?service=WANIPConn1'), ('SCPDURL', '/WANIPConnection.xml')])},
|
||||
'm_search_args': OrderedDict([('HOST', '239.255.255.250:1900'), ('MAN', 'ssdp:discover'), ('MX', 1),
|
||||
('ST', 'urn:schemas-upnp-org:device:WANDevice:1')]), 'reply': OrderedDict(
|
||||
'reply': OrderedDict(
|
||||
[('CACHE_CONTROL', 'max-age=1800'), ('LOCATION', 'http://10.0.0.1:49152/InternetGatewayDevice.xml'),
|
||||
('SERVER', 'Linux, UPnP/1.0, DIR-890L Ver 1.20'), ('ST', 'urn:schemas-upnp-org:device:WANDevice:1'),
|
||||
('USN', 'uuid:11111111-2222-3333-4444-555555555555::urn:schemas-upnp-org:device:WANDevice:1')]),
|
||||
|
@ -239,7 +238,7 @@ class TestDiscoverDLinkDIR890L(AsyncioTestCase):
|
|||
async def test_discover_commands(self):
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(
|
||||
SSDPDatagram("OK", self.gateway_info['reply']), self.gateway_info['m_search_args'],
|
||||
SSDPDatagram("OK", self.gateway_info['reply']),
|
||||
self.client_address, self.gateway_info['gateway_address'], loop=self.loop
|
||||
)
|
||||
await gateway.discover_commands()
|
||||
|
@ -274,9 +273,7 @@ class TestDiscoverNetgearNighthawkAC2350(TestDiscoverDLinkDIR890L):
|
|||
[('serviceType', 'urn:schemas-upnp-org:service:WANIPConnection:1'),
|
||||
('serviceId', 'urn:upnp-org:serviceId:WANIPConn1'), ('controlURL', '/ctl/IPConn'),
|
||||
('eventSubURL', '/evt/IPConn'), ('SCPDURL', '/WANIPCn.xml')])},
|
||||
'm_search_args': OrderedDict(
|
||||
[('HOST', '239.255.255.250:1900'), ('MAN', '"ssdp:discover"'), ('MX', 1),
|
||||
('ST', 'upnp:rootdevice')]), 'reply': OrderedDict(
|
||||
'reply': OrderedDict(
|
||||
[('CACHE_CONTROL', 'max-age=1800'), ('ST', 'upnp:rootdevice'),
|
||||
('USN', 'uuid:11111111-2222-3333-4444-555555555555::upnp:rootdevice'),
|
||||
('Server', 'R7500v2 UPnP/1.0 miniupnpd/1.0'), ('Location', 'http://192.168.0.1:5555/rootDesc.xml')]),
|
||||
|
|
|
@ -45,7 +45,7 @@ class TestGetExternalIPAddress(UPnPCommandTestCase):
|
|||
self.replies.update({request: b"HTTP/1.1 200 OK\r\nServer: WebServer\r\nDate: Wed, 22 May 2019 03:25:57 GMT\r\nConnection: close\r\nCONTENT-TYPE: text/xml; charset=\"utf-8\"\r\nCONTENT-LENGTH: 365 \r\nEXT:\r\n\r\n<?xml version=\"1.0\"?>\n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n\t<s:Body>\n\t\t<u:GetExternalIPAddressResponse xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\n<NewExternalIPAddress>11.222.3.44</NewExternalIPAddress>\n</u:GetExternalIPAddressResponse>\n\t</s:Body>\n</s:Envelope>\n"})
|
||||
self.addCleanup(self.replies.pop, request)
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
external_ip = await upnp.get_external_ip()
|
||||
|
@ -57,7 +57,7 @@ class TestGetExternalIPAddress(UPnPCommandTestCase):
|
|||
request: b"HTTP/1.1 200 OK\r\nServer: WebServer\r\nDate: Wed, 22 May 2019 03:25:57 GMT\r\nConnection: close\r\nCONTENT-TYPE: text/xml; charset=\"utf-8\"\r\nCONTENT-LENGTH: 354 \r\nEXT:\r\n\r\n<?xml version=\"1.0\"?>\n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n\t<s:Body>\n\t\t<u:GetExternalIPAddressResponse xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">\n<NewExternalIPAddress></NewExternalIPAddress>\n</u:GetExternalIPAddressResponse>\n\t</s:Body>\n</s:Envelope>\n"})
|
||||
self.addCleanup(self.replies.pop, request)
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
with self.assertRaises(UPnPError):
|
||||
|
@ -73,7 +73,7 @@ class TestMalformedGetExternalIPAddressResponse(UPnPCommandTestCase):
|
|||
b"<derp>11.222.3.44</derp>\n</u:GetExternalIPAddressResponse>\n\t</s:Body>\n</s:Envelope>\n"})
|
||||
self.addCleanup(self.replies.pop, self.get_ip_request)
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
with self.assertRaises(UPnPError):
|
||||
|
@ -84,7 +84,7 @@ class TestMalformedGetExternalIPAddressResponse(UPnPCommandTestCase):
|
|||
b"<newexternalipaddress>11.222.3.44</newexternalipaddress>\n</u:GetExternalIPAddressResponse>\n\t</s:Body>\n</s:Envelope>\n"})
|
||||
self.addCleanup(self.replies.pop, self.get_ip_request)
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
external_ip = await upnp.get_external_ip()
|
||||
|
@ -95,7 +95,7 @@ class TestMalformedGetExternalIPAddressResponse(UPnPCommandTestCase):
|
|||
b"11.222.3.44\n</u:GetExternalIPAddressResponse>\n\t</s:Body>\n</s:Envelope>\n"})
|
||||
self.addCleanup(self.replies.pop, self.get_ip_request)
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
external_ip = await upnp.get_external_ip()
|
||||
|
@ -113,7 +113,7 @@ class TestGetGenericPortMappingEntry(UPnPCommandTestCase):
|
|||
|
||||
async def test_get_port_mapping_by_index(self):
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
result = await upnp.get_port_mapping_by_index(0)
|
||||
|
@ -135,7 +135,7 @@ class TestGetNextPortMapping(UPnPCommandTestCase):
|
|||
|
||||
async def test_get_next_mapping(self):
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
ext_port = await upnp.get_next_mapping(4567, "UDP", "aioupnp test mapping")
|
||||
|
@ -155,7 +155,7 @@ class TestGetSpecificPortMapping(UPnPCommandTestCase):
|
|||
|
||||
async def test_get_specific_port_mapping(self):
|
||||
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
|
||||
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address, loop=self.loop)
|
||||
gateway = Gateway(self.reply, self.client_address, self.gateway_address, loop=self.loop)
|
||||
await gateway.discover_commands()
|
||||
upnp = UPnP(self.client_address, self.gateway_address, gateway)
|
||||
try:
|
||||
|
|
Loading…
Reference in a new issue