try m-searching upnp and wifi alliance service strings by default

This commit is contained in:
Jack Robison 2018-10-09 11:43:12 -04:00
parent 1c20862b92
commit c8b2f0d5cc
No known key found for this signature in database
GPG key ID: DF25C68FE0239BB2
3 changed files with 28 additions and 17 deletions

View file

@ -1,7 +1,6 @@
import logging import logging
import sys import sys
from aioupnp.upnp import UPnP from aioupnp.upnp import UPnP
from aioupnp.constants import UPNP_ORG_IGD
log = logging.getLogger("aioupnp") log = logging.getLogger("aioupnp")
@ -47,7 +46,7 @@ def main():
'gateway_address': '', 'gateway_address': '',
'lan_address': '', 'lan_address': '',
'timeout': 1, 'timeout': 1,
'service': UPNP_ORG_IGD, 'service': '', # if not provided try all of them
'return_as_json': True 'return_as_json': True
} }

View file

@ -8,7 +8,8 @@ from asyncio.futures import Future
from asyncio.transports import DatagramTransport from asyncio.transports import DatagramTransport
from aioupnp.fault import UPnPError from aioupnp.fault import UPnPError
from aioupnp.serialization.ssdp import SSDPDatagram from aioupnp.serialization.ssdp import SSDPDatagram
from aioupnp.constants import UPNP_ORG_IGD, SSDP_IP_ADDRESS, SSDP_PORT, SSDP_DISCOVER, SSDP_ROOT_DEVICE from aioupnp.constants import UPNP_ORG_IGD, WIFI_ALLIANCE_ORG_IGD
from aioupnp.constants import SSDP_IP_ADDRESS, SSDP_PORT, SSDP_DISCOVER, SSDP_ROOT_DEVICE
from aioupnp.protocols.multicast import MulticastProtocol from aioupnp.protocols.multicast import MulticastProtocol
ADDRESS_REGEX = re.compile("^http:\/\/(\d+\.\d+\.\d+\.\d+)\:(\d*)(\/[\w|\/|\:|\-|\.]*)$") ADDRESS_REGEX = re.compile("^http:\/\/(\d+\.\d+\.\d+\.\d+)\:(\d*)(\/[\w|\/|\:|\-|\.]*)$")
@ -32,21 +33,33 @@ class SSDPProtocol(MulticastProtocol):
log.debug("sending packet to %s:%i: %s", address, SSDP_PORT, packet) log.debug("sending packet to %s:%i: %s", address, SSDP_PORT, packet)
self.transport.sendto(packet.encode().encode(), (address, SSDP_PORT)) self.transport.sendto(packet.encode().encode(), (address, SSDP_PORT))
async def m_search(self, address, timeout: int = 1, service=UPNP_ORG_IGD) -> SSDPDatagram: async def m_search(self, address, timeout: int = 1, service='') -> SSDPDatagram:
if (address, service) in self.discover_callbacks: if (address, service) in self.discover_callbacks:
return self.discover_callbacks[(address, service)] return self.discover_callbacks[(address, service)]
# D-Link works with both if not service:
services = [UPNP_ORG_IGD, WIFI_ALLIANCE_ORG_IGD]
else:
services = [service]
# Cisco only works with quotes search_futs: List[Future] = []
self.send_m_search_packet(service, address, '\"%s\"' % SSDP_DISCOVER) outer_fut: Future = Future()
# DD-WRT only works without quotes for service in services:
self.send_m_search_packet(service, address, SSDP_DISCOVER) # D-Link works with both
f: Future = Future() # Cisco only works with quotes
self.discover_callbacks[(address, service)] = f self.send_m_search_packet(service, address, '\"%s\"' % SSDP_DISCOVER)
return await asyncio.wait_for(f, timeout)
# DD-WRT only works without quotes
self.send_m_search_packet(service, address, SSDP_DISCOVER)
f: Future = Future()
f.add_done_callback(lambda _f: outer_fut.set_result(_f.result()))
self.discover_callbacks[(address, service)] = f
search_futs.append(f)
return await asyncio.wait_for(outer_fut, timeout)
def datagram_received(self, data, addr) -> None: def datagram_received(self, data, addr) -> None:
if addr[0] == self.lan_address: if addr[0] == self.lan_address:
@ -106,7 +119,7 @@ async def listen_ssdp(lan_address: str, gateway_address: str,
async def m_search(lan_address: str, gateway_address: str, timeout: int = 1, async def m_search(lan_address: str, gateway_address: str, timeout: int = 1,
service: str = UPNP_ORG_IGD, ssdp_socket: socket.socket = None) -> SSDPDatagram: service: str = '', ssdp_socket: socket.socket = None) -> SSDPDatagram:
transport, protocol, gateway_address, lan_address = await listen_ssdp( transport, protocol, gateway_address, lan_address = await listen_ssdp(
lan_address, gateway_address, ssdp_socket lan_address, gateway_address, ssdp_socket
) )

View file

@ -6,7 +6,6 @@ import asyncio
from typing import Tuple, Dict, List, Union from typing import Tuple, Dict, List, Union
from aioupnp.fault import UPnPError from aioupnp.fault import UPnPError
from aioupnp.gateway import Gateway from aioupnp.gateway import Gateway
from aioupnp.constants import UPNP_ORG_IGD
from aioupnp.util import get_gateway_and_lan_addresses from aioupnp.util import get_gateway_and_lan_addresses
from aioupnp.protocols.ssdp import m_search from aioupnp.protocols.ssdp import m_search
@ -43,7 +42,7 @@ class UPnP:
@classmethod @classmethod
async def discover(cls, lan_address: str = '', gateway_address: str = '', timeout: int = 1, async def discover(cls, lan_address: str = '', gateway_address: str = '', timeout: int = 1,
service: str = UPNP_ORG_IGD, interface_name: str = 'default', service: str = '', interface_name: str = 'default',
ssdp_socket: socket.socket = None, soap_socket: socket.socket = None): ssdp_socket: socket.socket = None, soap_socket: socket.socket = None):
try: try:
lan_address, gateway_address = cls.get_lan_and_gateway(lan_address, gateway_address, interface_name) lan_address, gateway_address = cls.get_lan_and_gateway(lan_address, gateway_address, interface_name)
@ -55,7 +54,7 @@ class UPnP:
@classmethod @classmethod
@cli @cli
async def m_search(cls, lan_address: str = '', gateway_address: str = '', timeout: int = 1, async def m_search(cls, lan_address: str = '', gateway_address: str = '', timeout: int = 1,
service: str = UPNP_ORG_IGD, interface_name: str = 'default') -> Dict: service: str = '', interface_name: str = 'default') -> Dict:
lan_address, gateway_address = cls.get_lan_and_gateway(lan_address, gateway_address, interface_name) lan_address, gateway_address = cls.get_lan_and_gateway(lan_address, gateway_address, interface_name)
datagram = await m_search(lan_address, gateway_address, timeout, service) datagram = await m_search(lan_address, gateway_address, timeout, service)
return { return {
@ -215,7 +214,7 @@ class UPnP:
@classmethod @classmethod
def run_cli(cls, method, lan_address: str = '', gateway_address: str = '', timeout: int = 60, def run_cli(cls, method, lan_address: str = '', gateway_address: str = '', timeout: int = 60,
service: str = UPNP_ORG_IGD, interface_name: str = 'default', service: str = '', interface_name: str = 'default',
kwargs: dict = None) -> None: kwargs: dict = None) -> None:
kwargs = kwargs or {} kwargs = kwargs or {}